UNPKG

@kya-os/mcp-i

Version:

COMING SOON:Production-ready MCP Identity with automatic registration, key rotation, and optimized performance

160 lines 4.95 kB
/** * Storage abstraction for MCP-I identity * Supports both file-based and in-memory storage for different runtime environments */ import * as fs from 'fs'; import * as path from 'path'; /** * File-based storage for traditional Node.js environments */ export class FileStorage { filePath; constructor(customPath) { this.filePath = customPath || path.join(process.cwd(), '.mcp-identity.json'); } async load() { try { if (fs.existsSync(this.filePath)) { const content = fs.readFileSync(this.filePath, 'utf-8'); return JSON.parse(content); } } catch { // Ignore errors } return null; } async save(identity) { fs.writeFileSync(this.filePath, JSON.stringify(identity, null, 2)); } async exists() { return fs.existsSync(this.filePath); } } /** * In-memory storage for Lambda/Edge runtime environments */ export class MemoryStorage { static instances = new Map(); key; constructor(key) { // Use a unique key for this instance (e.g., based on agent name) this.key = key || 'default'; } async load() { return MemoryStorage.instances.get(this.key) || null; } async save(identity) { MemoryStorage.instances.set(this.key, identity); } async exists() { return MemoryStorage.instances.has(this.key); } /** * Clear all stored identities (useful for testing) */ static clear() { MemoryStorage.instances.clear(); } } /** * Environment variable storage loader * This works with both file and memory storage as a fallback */ export class EnvironmentStorage { static load() { if (process.env.AGENT_DID && process.env.AGENT_PUBLIC_KEY && process.env.AGENT_PRIVATE_KEY) { return { did: process.env.AGENT_DID, publicKey: process.env.AGENT_PUBLIC_KEY, privateKey: process.env.AGENT_PRIVATE_KEY, agentId: process.env.AGENT_ID || '', agentSlug: process.env.AGENT_SLUG || '', registeredAt: process.env.AGENT_REGISTERED_AT || new Date().toISOString() }; } return null; } } /** * Combined storage that tries multiple providers in order */ export class CombinedStorage { providers; primaryProvider; constructor(providers) { if (providers.length === 0) { throw new Error('At least one storage provider is required'); } this.providers = providers; this.primaryProvider = providers[0]; } async load() { // Try environment variables first const envIdentity = EnvironmentStorage.load(); if (envIdentity) { return envIdentity; } // Try each provider in order for (const provider of this.providers) { const identity = await provider.load(); if (identity) { return identity; } } return null; } async save(identity) { // Save to primary provider only await this.primaryProvider.save(identity); } async exists() { // Check if identity exists in any provider for (const provider of this.providers) { if (await provider.exists()) { return true; } } return false; } } /** * Storage factory based on runtime detection */ export class StorageFactory { static create(options) { const storageType = options?.storage || 'auto'; let baseStorage; if (storageType === 'memory') { baseStorage = new MemoryStorage(options?.memoryKey); } else if (storageType === 'file') { baseStorage = new FileStorage(options?.customPath); } else if (storageType === 'auto') { // Auto-detect based on runtime // Check if we're in a Lambda/Edge environment if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.VERCEL || process.env.NETLIFY || !fs.existsSync || typeof fs.writeFileSync !== 'function') { baseStorage = new MemoryStorage(options?.memoryKey); } else { // Default to file storage for Node.js baseStorage = new FileStorage(options?.customPath); } } else { throw new Error(`Unknown storage type: ${storageType}`); } // Wrap with encryption if password provided if (options?.encryptionPassword) { const { createEncryptedStorage } = require('./encrypted-storage'); return createEncryptedStorage(baseStorage, options.encryptionPassword); } return baseStorage; } } //# sourceMappingURL=storage.js.map