@kya-os/mcp-i 0.1.0-alpha.2.3 → 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.
- package/README.md +192 -216
- package/dist/auto.d.ts +0 -12
- package/dist/auto.js +3 -14
- package/dist/crypto.d.ts +10 -26
- package/dist/crypto.js +117 -37
- package/dist/dev-helper.d.ts +3 -0
- package/dist/dev-helper.js +54 -0
- package/dist/encrypted-storage.d.ts +11 -0
- package/dist/encrypted-storage.js +73 -0
- package/dist/index.d.ts +29 -106
- package/dist/index.js +225 -392
- package/dist/logger.d.ts +32 -0
- package/dist/logger.js +66 -0
- package/dist/registry/index.d.ts +0 -31
- package/dist/registry/index.js +2 -42
- package/dist/registry/knowthat.d.ts +3 -18
- package/dist/registry/knowthat.js +10 -35
- package/dist/rotation.d.ts +35 -0
- package/dist/rotation.js +102 -0
- package/dist/storage.d.ts +41 -0
- package/dist/storage.js +163 -0
- package/dist/transport.d.ts +34 -0
- package/dist/transport.js +207 -0
- package/dist/types.d.ts +72 -99
- package/dist/types.js +0 -4
- package/package.json +16 -6
- package/dist/__tests__/challenge-response.test.d.ts +0 -5
- package/dist/__tests__/challenge-response.test.d.ts.map +0 -1
- package/dist/__tests__/challenge-response.test.js +0 -218
- package/dist/__tests__/challenge-response.test.js.map +0 -1
- package/dist/__tests__/crypto.test.d.ts +0 -5
- package/dist/__tests__/crypto.test.d.ts.map +0 -1
- package/dist/__tests__/crypto.test.js +0 -153
- package/dist/__tests__/crypto.test.js.map +0 -1
- package/dist/auto.d.ts.map +0 -1
- package/dist/auto.js.map +0 -1
- package/dist/crypto.d.ts.map +0 -1
- package/dist/crypto.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/registry/cursor.d.ts +0 -25
- package/dist/registry/cursor.d.ts.map +0 -1
- package/dist/registry/cursor.js +0 -108
- package/dist/registry/cursor.js.map +0 -1
- package/dist/registry/glama.d.ts +0 -25
- package/dist/registry/glama.d.ts.map +0 -1
- package/dist/registry/glama.js +0 -111
- package/dist/registry/glama.js.map +0 -1
- package/dist/registry/index.d.ts.map +0 -1
- package/dist/registry/index.js.map +0 -1
- package/dist/registry/knowthat.d.ts.map +0 -1
- package/dist/registry/knowthat.js.map +0 -1
- package/dist/registry/smithery.d.ts +0 -29
- package/dist/registry/smithery.d.ts.map +0 -1
- package/dist/registry/smithery.js +0 -119
- package/dist/registry/smithery.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
53
|
-
const
|
|
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
|
|
56
|
-
privateKey
|
|
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
|
|
68
|
-
|
|
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
|
|
106
|
+
return await ed.verifyAsync(signature, messageBuffer, publicKey);
|
|
81
107
|
}
|
|
82
108
|
catch {
|
|
83
109
|
return false;
|
|
84
110
|
}
|
|
85
111
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initWithDevExperience = initWithDevExperience;
|
|
4
|
+
exports.showAgentStatus = showAgentStatus;
|
|
5
|
+
const index_1 = require("./index");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
async function initWithDevExperience(options = {}) {
|
|
8
|
+
const logger = (0, logger_1.getLogger)();
|
|
9
|
+
if (process.env.NODE_ENV === 'development' && !options.mode) {
|
|
10
|
+
options.mode = 'development';
|
|
11
|
+
logger.info('🔧 Development mode detected - agents will be created as drafts');
|
|
12
|
+
}
|
|
13
|
+
if (!options.name && !process.env.MCP_SERVER_NAME) {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = require(process.cwd() + '/package.json');
|
|
16
|
+
options.name = pkg.name || 'Unnamed MCP Server';
|
|
17
|
+
options.description = pkg.description;
|
|
18
|
+
options.repository = pkg.repository?.url || pkg.repository;
|
|
19
|
+
logger.info(`📦 Auto-detected agent name: ${options.name}`);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
options.name = 'Development MCP Server';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!options.storage) {
|
|
26
|
+
logger.info('💡 Tip: Use storage: "file" for persistent identity across restarts');
|
|
27
|
+
}
|
|
28
|
+
const identity = await index_1.MCPIdentity.init(options);
|
|
29
|
+
logger.info('✨ MCP Identity initialized successfully!');
|
|
30
|
+
logger.info(`🆔 DID: ${identity.did}`);
|
|
31
|
+
const { claimUrl } = await identity.requestEditAccess();
|
|
32
|
+
logger.info(`🔗 Claim your agent: ${claimUrl}`);
|
|
33
|
+
logger.info('💡 Your MCP server responses are now automatically signed with your agent identity');
|
|
34
|
+
return identity;
|
|
35
|
+
}
|
|
36
|
+
function showAgentStatus(identity) {
|
|
37
|
+
const logger = (0, logger_1.getLogger)();
|
|
38
|
+
const capabilities = identity.getCapabilities();
|
|
39
|
+
logger.info('📊 Agent Status:');
|
|
40
|
+
logger.info(` DID: ${identity.did}`);
|
|
41
|
+
logger.info(` Conformance Level: ${capabilities.conformanceLevel}`);
|
|
42
|
+
logger.info(` Registry: ${capabilities.registry || 'knowthat.ai'}`);
|
|
43
|
+
logger.info(` Handshake Supported: ${capabilities.handshakeSupported}`);
|
|
44
|
+
const directories = identity.getDirectories();
|
|
45
|
+
if (directories === 'none') {
|
|
46
|
+
logger.info('📋 Directories: Not listing on any directories');
|
|
47
|
+
}
|
|
48
|
+
else if (directories === 'verified') {
|
|
49
|
+
logger.info('📋 Directories: Listing on all verified directories');
|
|
50
|
+
}
|
|
51
|
+
else if (Array.isArray(directories)) {
|
|
52
|
+
logger.info(`📋 Directories: ${directories.join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { StorageProvider } from './storage';
|
|
2
|
+
import { PersistedIdentity } from './types';
|
|
3
|
+
export declare class EncryptedStorage implements StorageProvider {
|
|
4
|
+
private baseStorage;
|
|
5
|
+
private password;
|
|
6
|
+
constructor(baseStorage: StorageProvider, password: string);
|
|
7
|
+
load(): Promise<PersistedIdentity | null>;
|
|
8
|
+
save(identity: PersistedIdentity): Promise<void>;
|
|
9
|
+
exists(): Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export declare function createEncryptedStorage(baseStorage: StorageProvider, password: string): StorageProvider;
|
|
@@ -0,0 +1,73 @@
|
|
|
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.EncryptedStorage = void 0;
|
|
37
|
+
exports.createEncryptedStorage = createEncryptedStorage;
|
|
38
|
+
const crypto = __importStar(require("./crypto"));
|
|
39
|
+
class EncryptedStorage {
|
|
40
|
+
constructor(baseStorage, password) {
|
|
41
|
+
this.baseStorage = baseStorage;
|
|
42
|
+
this.password = password;
|
|
43
|
+
}
|
|
44
|
+
async load() {
|
|
45
|
+
const identity = await this.baseStorage.load();
|
|
46
|
+
if (!identity) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
if (identity.privateKey.startsWith('enc:')) {
|
|
50
|
+
try {
|
|
51
|
+
identity.privateKey = await crypto.decrypt(identity.privateKey, this.password);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw new Error('Failed to decrypt stored identity - invalid password');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return identity;
|
|
58
|
+
}
|
|
59
|
+
async save(identity) {
|
|
60
|
+
const encryptedIdentity = { ...identity };
|
|
61
|
+
if (!encryptedIdentity.privateKey.startsWith('enc:')) {
|
|
62
|
+
encryptedIdentity.privateKey = await crypto.encrypt(encryptedIdentity.privateKey, this.password);
|
|
63
|
+
}
|
|
64
|
+
await this.baseStorage.save(encryptedIdentity);
|
|
65
|
+
}
|
|
66
|
+
async exists() {
|
|
67
|
+
return this.baseStorage.exists();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.EncryptedStorage = EncryptedStorage;
|
|
71
|
+
function createEncryptedStorage(baseStorage, password) {
|
|
72
|
+
return new EncryptedStorage(baseStorage, password);
|
|
73
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Enable any MCP server to get a verifiable identity with just 2 lines of code:
|
|
5
|
-
*
|
|
6
|
-
* ```typescript
|
|
7
|
-
* import "@kya-os/mcp-i/auto"; // That's it! Your server now has identity
|
|
8
|
-
* ```
|
|
9
|
-
*
|
|
10
|
-
* Or with configuration:
|
|
11
|
-
* ```typescript
|
|
12
|
-
* import { enableMCPIdentity } from "@kya-os/mcp-i";
|
|
13
|
-
* await enableMCPIdentity({ name: "My Amazing Agent" });
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* Future multi-registry support:
|
|
17
|
-
* ```typescript
|
|
18
|
-
* await enableMCPIdentity({
|
|
19
|
-
* name: "My Agent",
|
|
20
|
-
* // Additional registries will be supported as directories adopt MCP-I
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
import { MCPIdentityOptions, Challenge, ChallengeResponse, MCPICapabilities, SignedResponse, RegistryStatus, RegistryName } from './types';
|
|
1
|
+
import { MCPIdentityOptions, Challenge, ChallengeResponse, MCPICapabilities, SignedResponse, MCPMiddleware, DirectoryPreference } from './types';
|
|
2
|
+
import { KeyRotationResult, KeyHealth } from './rotation';
|
|
25
3
|
export * from './types';
|
|
26
4
|
export { RegistryFactory, REGISTRY_TIERS, resolveRegistries } from './registry';
|
|
5
|
+
export { LoggerFactory, ConsoleLogger, SilentLogger } from './logger';
|
|
6
|
+
export { StorageFactory, MemoryStorage, FileStorage } from './storage';
|
|
7
|
+
export { TransportFactory, RuntimeDetector } from './transport';
|
|
8
|
+
export { KeyRotationManager } from './rotation';
|
|
9
|
+
export { initWithDevExperience, showAgentStatus } from './dev-helper';
|
|
27
10
|
export declare class MCPIdentity {
|
|
28
11
|
readonly did: string;
|
|
29
12
|
readonly publicKey: string;
|
|
@@ -32,100 +15,40 @@ export declare class MCPIdentity {
|
|
|
32
15
|
private enableNonceTracking;
|
|
33
16
|
private usedNonces;
|
|
34
17
|
private nonceCleanupInterval?;
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
private
|
|
18
|
+
private encryptionPassword?;
|
|
19
|
+
private decryptedPrivateKey?;
|
|
20
|
+
private directories;
|
|
21
|
+
private storage;
|
|
22
|
+
private transport;
|
|
23
|
+
private logger;
|
|
24
|
+
private rotationManager?;
|
|
25
|
+
private precomputed;
|
|
38
26
|
private constructor();
|
|
39
|
-
/**
|
|
40
|
-
* Initialize MCP Identity - the main entry point
|
|
41
|
-
*
|
|
42
|
-
* IMPORTANT: This only makes API calls in these cases:
|
|
43
|
-
* 1. First time ever (no identity exists) - registers with all specified registries
|
|
44
|
-
* 2. Adding new registries to existing identity - only calls the new registries
|
|
45
|
-
*
|
|
46
|
-
* After initial registration, all subsequent calls load from disk with NO API calls.
|
|
47
|
-
*/
|
|
48
27
|
static init(options?: MCPIdentityOptions): Promise<MCPIdentity>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Add a new registry
|
|
58
|
-
*/
|
|
59
|
-
addRegistry(registryName: RegistryName): Promise<void>;
|
|
60
|
-
/**
|
|
61
|
-
* Add multiple registries
|
|
62
|
-
*/
|
|
63
|
-
addRegistries(registryNames: RegistryName[]): Promise<void>;
|
|
64
|
-
/**
|
|
65
|
-
* Get current registry status
|
|
66
|
-
*/
|
|
67
|
-
getRegistryStatus(): RegistryStatus[];
|
|
68
|
-
/**
|
|
69
|
-
* Check if registered with a specific registry
|
|
70
|
-
*/
|
|
71
|
-
isRegisteredWith(registryName: RegistryName): boolean;
|
|
72
|
-
/**
|
|
73
|
-
* Sign a message with the agent's private key using Ed25519
|
|
74
|
-
*/
|
|
28
|
+
enableAutoRotation(policy?: {
|
|
29
|
+
maxAge?: number;
|
|
30
|
+
maxSignatures?: number;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
rotateKeys(reason?: string): Promise<KeyRotationResult>;
|
|
33
|
+
checkKeyHealth(): KeyHealth | null;
|
|
34
|
+
private getPrivateKey;
|
|
75
35
|
sign(message: string | Buffer): Promise<string>;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
36
|
+
requestEditAccess(): Promise<{
|
|
37
|
+
editUrl: string;
|
|
38
|
+
claimUrl?: string;
|
|
39
|
+
}>;
|
|
79
40
|
verify(message: string | Buffer, signature: string, publicKey?: string): Promise<boolean>;
|
|
80
|
-
/**
|
|
81
|
-
* Respond to an MCP-I challenge
|
|
82
|
-
*/
|
|
83
41
|
respondToChallenge(challenge: Challenge): Promise<ChallengeResponse>;
|
|
84
|
-
/**
|
|
85
|
-
* Get MCP-I capabilities for advertisement
|
|
86
|
-
*/
|
|
87
42
|
getCapabilities(): MCPICapabilities;
|
|
88
|
-
/**
|
|
89
|
-
* Sign an MCP response with identity metadata
|
|
90
|
-
*/
|
|
91
43
|
signResponse<T = any>(response: T): Promise<SignedResponse<T>>;
|
|
92
|
-
/**
|
|
93
|
-
* Generate a new nonce for challenges
|
|
94
|
-
*/
|
|
95
44
|
static generateNonce(): string;
|
|
96
|
-
|
|
97
|
-
* Request edit access to agent profile
|
|
98
|
-
* Returns a signed URL for editing the agent on the registry
|
|
99
|
-
*/
|
|
100
|
-
requestEditAccess(registryName?: string): Promise<string>;
|
|
101
|
-
/**
|
|
102
|
-
* Clean up old nonces periodically to prevent memory leaks
|
|
103
|
-
*/
|
|
45
|
+
getDirectories(): DirectoryPreference;
|
|
104
46
|
private startNonceCleanup;
|
|
105
|
-
/**
|
|
106
|
-
* Clean up resources
|
|
107
|
-
*/
|
|
108
47
|
destroy(): void;
|
|
109
|
-
/**
|
|
110
|
-
* Helper to extract agent name from DID
|
|
111
|
-
*/
|
|
112
48
|
private extractAgentName;
|
|
113
|
-
/**
|
|
114
|
-
* Helper to extract agent ID
|
|
115
|
-
*/
|
|
116
49
|
private extractAgentId;
|
|
117
|
-
/**
|
|
118
|
-
* Helper to extract agent slug
|
|
119
|
-
*/
|
|
120
50
|
private extractAgentSlug;
|
|
121
|
-
|
|
122
|
-
* Persist updated registry status
|
|
123
|
-
*/
|
|
124
|
-
private persistRegistryStatus;
|
|
51
|
+
private persistIdentity;
|
|
125
52
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Enable MCP Identity for any MCP server
|
|
128
|
-
* This is the main integration point that patches the MCP Server
|
|
129
|
-
*/
|
|
130
53
|
export declare function enableMCPIdentity(options?: MCPIdentityOptions): Promise<MCPIdentity>;
|
|
131
|
-
|
|
54
|
+
export declare function createMCPMiddleware(identity: MCPIdentity): MCPMiddleware;
|