@nextnext/mcp-server 0.1.1 → 0.1.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/dist/index.js +74 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51168,15 +51168,49 @@ var require_main3 = __commonJS((exports) => {
|
|
|
51168
51168
|
|
|
51169
51169
|
// src/crypto/encryption.ts
|
|
51170
51170
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes5 } from "crypto";
|
|
51171
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
51172
|
+
import { homedir } from "os";
|
|
51173
|
+
import { join as join3 } from "path";
|
|
51174
|
+
function getOrCreateLocalKey() {
|
|
51175
|
+
if (existsSync(LOCAL_KEY_FILE)) {
|
|
51176
|
+
try {
|
|
51177
|
+
const keyHex2 = readFileSync(LOCAL_KEY_FILE, "utf-8").trim();
|
|
51178
|
+
if (keyHex2.length === 64) {
|
|
51179
|
+
console.error("[Encryption] Using local key from ~/.nextnext/encryption.key");
|
|
51180
|
+
return Buffer.from(keyHex2, "hex");
|
|
51181
|
+
}
|
|
51182
|
+
} catch (error2) {
|
|
51183
|
+
console.error("[Encryption] Error reading local key, generating new one");
|
|
51184
|
+
}
|
|
51185
|
+
}
|
|
51186
|
+
const newKey = randomBytes5(32);
|
|
51187
|
+
const keyHex = newKey.toString("hex");
|
|
51188
|
+
try {
|
|
51189
|
+
if (!existsSync(LOCAL_KEY_DIR)) {
|
|
51190
|
+
mkdirSync(LOCAL_KEY_DIR, { recursive: true, mode: 448 });
|
|
51191
|
+
}
|
|
51192
|
+
writeFileSync(LOCAL_KEY_FILE, keyHex, { mode: 384 });
|
|
51193
|
+
console.error("[Encryption] Generated and saved local key to ~/.nextnext/encryption.key");
|
|
51194
|
+
} catch (error2) {
|
|
51195
|
+
console.error("[Encryption] Could not save local key, using session-only key");
|
|
51196
|
+
}
|
|
51197
|
+
return newKey;
|
|
51198
|
+
}
|
|
51171
51199
|
function getEncryptionKey() {
|
|
51172
|
-
|
|
51173
|
-
|
|
51174
|
-
throw new Error("SERVER_ENCRYPTION_KEY environment variable not set");
|
|
51200
|
+
if (cachedEncryptionKey) {
|
|
51201
|
+
return cachedEncryptionKey;
|
|
51175
51202
|
}
|
|
51176
|
-
|
|
51177
|
-
|
|
51203
|
+
const envKey = process.env.SERVER_ENCRYPTION_KEY;
|
|
51204
|
+
if (envKey) {
|
|
51205
|
+
if (envKey.length !== 64) {
|
|
51206
|
+
throw new Error("SERVER_ENCRYPTION_KEY must be 64 hex characters (32 bytes)");
|
|
51207
|
+
}
|
|
51208
|
+
cachedEncryptionKey = Buffer.from(envKey, "hex");
|
|
51209
|
+
console.error("[Encryption] Using SERVER_ENCRYPTION_KEY from environment");
|
|
51210
|
+
return cachedEncryptionKey;
|
|
51178
51211
|
}
|
|
51179
|
-
|
|
51212
|
+
cachedEncryptionKey = getOrCreateLocalKey();
|
|
51213
|
+
return cachedEncryptionKey;
|
|
51180
51214
|
}
|
|
51181
51215
|
function encryptNostrKey(privateKey) {
|
|
51182
51216
|
const key = getEncryptionKey();
|
|
@@ -51214,11 +51248,14 @@ function isEncryptedNostrKey(value) {
|
|
|
51214
51248
|
function generateEncryptionKey() {
|
|
51215
51249
|
return randomBytes5(32).toString("hex");
|
|
51216
51250
|
}
|
|
51251
|
+
var cachedEncryptionKey = null, LOCAL_KEY_DIR, LOCAL_KEY_FILE;
|
|
51217
51252
|
var init_encryption = __esm(() => {
|
|
51253
|
+
LOCAL_KEY_DIR = join3(homedir(), ".nextnext");
|
|
51254
|
+
LOCAL_KEY_FILE = join3(LOCAL_KEY_DIR, "encryption.key");
|
|
51218
51255
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
51219
51256
|
if (process.argv.includes("--generate-key")) {
|
|
51220
|
-
console.
|
|
51221
|
-
console.
|
|
51257
|
+
console.error("Generated SERVER_ENCRYPTION_KEY:");
|
|
51258
|
+
console.error(generateEncryptionKey());
|
|
51222
51259
|
}
|
|
51223
51260
|
}
|
|
51224
51261
|
});
|
|
@@ -54223,19 +54260,19 @@ function initRedis() {
|
|
|
54223
54260
|
if (url3 && token) {
|
|
54224
54261
|
redisClient = new Redis2({ url: url3, token });
|
|
54225
54262
|
useRedis = true;
|
|
54226
|
-
console.
|
|
54263
|
+
console.error("[Redis] Connected via Upstash REST API");
|
|
54227
54264
|
return true;
|
|
54228
54265
|
} else if (url3) {
|
|
54229
54266
|
try {
|
|
54230
54267
|
redisClient = Redis2.fromEnv();
|
|
54231
54268
|
useRedis = true;
|
|
54232
|
-
console.
|
|
54269
|
+
console.error("[Redis] Connected via REDIS_URL");
|
|
54233
54270
|
return true;
|
|
54234
54271
|
} catch (e7) {
|
|
54235
54272
|
console.warn("[Redis] Failed to connect, falling back to in-memory storage");
|
|
54236
54273
|
}
|
|
54237
54274
|
}
|
|
54238
|
-
console.
|
|
54275
|
+
console.error("[Redis] Not configured, using in-memory storage (data will not survive restarts)");
|
|
54239
54276
|
return false;
|
|
54240
54277
|
}
|
|
54241
54278
|
async function getIdentity(pubkey) {
|
|
@@ -54313,7 +54350,7 @@ async function markSessionInitialized(sessionId) {
|
|
|
54313
54350
|
if (useRedis && redisClient) {
|
|
54314
54351
|
try {
|
|
54315
54352
|
await redisClient.set(`${SESSION_PREFIX}${sessionId}`, state, { ex: SESSION_TTL });
|
|
54316
|
-
console.
|
|
54353
|
+
console.error(`[Redis] Session ${sessionId.slice(0, 8)} marked as initialized`);
|
|
54317
54354
|
} catch (error2) {
|
|
54318
54355
|
console.error("[Redis] Error marking session initialized:", error2);
|
|
54319
54356
|
}
|
|
@@ -54381,7 +54418,7 @@ __export(exports_context, {
|
|
|
54381
54418
|
import { AsyncLocalStorage } from "async_hooks";
|
|
54382
54419
|
function runWithSessionContext(sessionId, fn) {
|
|
54383
54420
|
const cachedIdentity = sessionIdentityCache.get(sessionId);
|
|
54384
|
-
console.
|
|
54421
|
+
console.error(`[runWithSessionContext] Session: ${sessionId.slice(0, 8)}, cached identity: ${cachedIdentity ? cachedIdentity.npub?.slice(0, 16) || "yes" : "none"}, cache size: ${sessionIdentityCache.size}`);
|
|
54385
54422
|
return sessionStorage.run({ sessionId, identity: cachedIdentity }, fn);
|
|
54386
54423
|
}
|
|
54387
54424
|
function getCurrentSessionId() {
|
|
@@ -54401,7 +54438,7 @@ async function authenticateSession(encryptedKey) {
|
|
|
54401
54438
|
let privateKeyHex;
|
|
54402
54439
|
try {
|
|
54403
54440
|
privateKeyHex = decryptNostrKey(encryptedKey);
|
|
54404
|
-
console.
|
|
54441
|
+
console.error(`[Session] Decrypted key length: ${privateKeyHex.length}, first4: ${privateKeyHex.slice(0, 4)}`);
|
|
54405
54442
|
} catch (error2) {
|
|
54406
54443
|
console.error(`[Session] Decryption failed:`, error2);
|
|
54407
54444
|
throw new Error(`Decryption failed: ${error2.message}. The key may have been created with a different server or is corrupted.`);
|
|
@@ -54413,10 +54450,10 @@ async function authenticateSession(encryptedKey) {
|
|
|
54413
54450
|
let pubkey;
|
|
54414
54451
|
let npub;
|
|
54415
54452
|
try {
|
|
54416
|
-
console.
|
|
54453
|
+
console.error(`[Session] Calling getPublicKey with hex (length=${privateKeyHex.length})`);
|
|
54417
54454
|
pubkey = getPublicKey2(privateKeyHex);
|
|
54418
54455
|
npub = nip19_exports.npubEncode(pubkey);
|
|
54419
|
-
console.
|
|
54456
|
+
console.error(`[Session] Derived pubkey: ${pubkey.slice(0, 8)}...`);
|
|
54420
54457
|
} catch (error2) {
|
|
54421
54458
|
console.error(`[Session] getPublicKey failed:`, error2);
|
|
54422
54459
|
throw new Error(`Failed to derive public key: ${error2.message}`);
|
|
@@ -54427,14 +54464,14 @@ async function authenticateSession(encryptedKey) {
|
|
|
54427
54464
|
npub
|
|
54428
54465
|
};
|
|
54429
54466
|
sessionIdentityCache.set(sessionId, identity);
|
|
54430
|
-
console.
|
|
54467
|
+
console.error(`[authenticateSession] Cached identity for session ${sessionId.slice(0, 8)}, cache size now: ${sessionIdentityCache.size}`);
|
|
54431
54468
|
const store = sessionStorage.getStore();
|
|
54432
54469
|
if (store) {
|
|
54433
54470
|
store.identity = identity;
|
|
54434
54471
|
}
|
|
54435
54472
|
const existingIdentity = await getIdentity(pubkey);
|
|
54436
54473
|
if (existingIdentity) {
|
|
54437
|
-
console.
|
|
54474
|
+
console.error(`[SessionContext] Returning user: ${npub.slice(0, 16)}... (sessions: ${existingIdentity.stats?.totalSessions || 0})`);
|
|
54438
54475
|
await recordNewSession(pubkey);
|
|
54439
54476
|
} else {
|
|
54440
54477
|
const newIdentity = {
|
|
@@ -54448,9 +54485,9 @@ async function authenticateSession(encryptedKey) {
|
|
|
54448
54485
|
}
|
|
54449
54486
|
};
|
|
54450
54487
|
await saveIdentity(pubkey, newIdentity);
|
|
54451
|
-
console.
|
|
54488
|
+
console.error(`[SessionContext] New user registered: ${npub.slice(0, 16)}...`);
|
|
54452
54489
|
}
|
|
54453
|
-
console.
|
|
54490
|
+
console.error(`[SessionContext] Session ${sessionId.slice(0, 8)}... authenticated as ${npub.slice(0, 16)}...`);
|
|
54454
54491
|
return identity;
|
|
54455
54492
|
}
|
|
54456
54493
|
function clearSessionIdentity() {
|
|
@@ -102131,7 +102168,7 @@ function getSupabaseClient() {
|
|
|
102131
102168
|
supabase = createClient2(url3, key, {
|
|
102132
102169
|
auth: { persistSession: false }
|
|
102133
102170
|
});
|
|
102134
|
-
console.
|
|
102171
|
+
console.error("[Supabase] Connected to:", url3);
|
|
102135
102172
|
return supabase;
|
|
102136
102173
|
}
|
|
102137
102174
|
function isSupabaseConfigured() {
|
|
@@ -102230,10 +102267,10 @@ async function createBurnerWallet(label, nostrPubkey) {
|
|
|
102230
102267
|
label,
|
|
102231
102268
|
nostrPubkey
|
|
102232
102269
|
});
|
|
102233
|
-
console.
|
|
102270
|
+
console.error(`[BurnerWallet] Created (Supabase): ${wallet.address} (${label || "unlabeled"}) ${nostrPubkey ? `linked to ${nostrPubkey.slice(0, 16)}...` : ""}`);
|
|
102234
102271
|
} else {
|
|
102235
102272
|
memoryWallets.set(wallet.id, wallet);
|
|
102236
|
-
console.
|
|
102273
|
+
console.error(`[BurnerWallet] Created (memory): ${wallet.address} (${label || "unlabeled"})`);
|
|
102237
102274
|
}
|
|
102238
102275
|
return wallet;
|
|
102239
102276
|
}
|
|
@@ -102415,7 +102452,7 @@ async function createPaymentAuthorization(walletId, recipientAddress, amountUsdc
|
|
|
102415
102452
|
r,
|
|
102416
102453
|
s: s3
|
|
102417
102454
|
};
|
|
102418
|
-
console.
|
|
102455
|
+
console.error(`[x402Payer] Created authorization: ${amountUsdc} USDC from ${account.address} to ${recipientAddress}`);
|
|
102419
102456
|
return {
|
|
102420
102457
|
success: true,
|
|
102421
102458
|
authorization,
|
|
@@ -102442,13 +102479,13 @@ function deriveEvmAddress(nostrPrivateKeyHex) {
|
|
|
102442
102479
|
}
|
|
102443
102480
|
function getCurrentIdentity() {
|
|
102444
102481
|
const sessionId = getCurrentSessionId();
|
|
102445
|
-
console.
|
|
102482
|
+
console.error(`[getCurrentIdentity] Session: ${sessionId?.slice(0, 8) || "none"}`);
|
|
102446
102483
|
const sessionIdentity = getSessionIdentity();
|
|
102447
102484
|
if (sessionIdentity) {
|
|
102448
|
-
console.
|
|
102485
|
+
console.error(`[getCurrentIdentity] Found identity: ${sessionIdentity.npub?.slice(0, 16) || sessionIdentity.pubkey.slice(0, 8)}`);
|
|
102449
102486
|
return { pubkey: sessionIdentity.pubkey, privateKeyHex: sessionIdentity.privateKeyHex };
|
|
102450
102487
|
}
|
|
102451
|
-
console.
|
|
102488
|
+
console.error(`[getCurrentIdentity] No session identity found`);
|
|
102452
102489
|
const privateKeyHex = process.env.NOSTR_PRIVATE_KEY_HEX;
|
|
102453
102490
|
if (privateKeyHex) {
|
|
102454
102491
|
try {
|
|
@@ -102684,7 +102721,7 @@ var identityTools = [
|
|
|
102684
102721
|
|
|
102685
102722
|
// src/tools/wallet-tools.ts
|
|
102686
102723
|
function identityRequiredResponse(toolName) {
|
|
102687
|
-
console.
|
|
102724
|
+
console.error(`[${toolName}] No identity found - session may have expired or instance restarted`);
|
|
102688
102725
|
return {
|
|
102689
102726
|
content: [{
|
|
102690
102727
|
type: "text",
|
|
@@ -102947,7 +102984,7 @@ var nostrClient = null;
|
|
|
102947
102984
|
function getNostrClient() {
|
|
102948
102985
|
if (!nostrClient) {
|
|
102949
102986
|
nostrClient = new NostrClient({ relayUrl: RELAY_URL });
|
|
102950
|
-
console.
|
|
102987
|
+
console.error(`[NostrTools] Initialized with pubkey: ${nostrClient.getPublicKey()}`);
|
|
102951
102988
|
}
|
|
102952
102989
|
return nostrClient;
|
|
102953
102990
|
}
|
|
@@ -102984,13 +103021,13 @@ var postIntentTool = {
|
|
|
102984
103021
|
const { authenticateSession: authenticateSession2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
102985
103022
|
await authenticateSession2(args.encryptedKey);
|
|
102986
103023
|
identity = getCurrentIdentity();
|
|
102987
|
-
console.
|
|
103024
|
+
console.error(`[post_intent] Auto-authenticated with provided key`);
|
|
102988
103025
|
} catch (error2) {
|
|
102989
103026
|
console.error(`[post_intent] Auto-auth failed: ${error2.message}`);
|
|
102990
103027
|
}
|
|
102991
103028
|
}
|
|
102992
103029
|
if (!identity) {
|
|
102993
|
-
console.
|
|
103030
|
+
console.error(`[post_intent] No identity found - session may have expired or instance restarted`);
|
|
102994
103031
|
return {
|
|
102995
103032
|
content: [{
|
|
102996
103033
|
type: "text",
|
|
@@ -103049,7 +103086,7 @@ var postIntentTool = {
|
|
|
103049
103086
|
};
|
|
103050
103087
|
} catch (error2) {
|
|
103051
103088
|
console.error("[postIntent] Error routing through Factory-API:", error2);
|
|
103052
|
-
console.
|
|
103089
|
+
console.error("[postIntent] Falling back to direct relay post...");
|
|
103053
103090
|
const client = getNostrClient();
|
|
103054
103091
|
const result = await client.postIntent(intent);
|
|
103055
103092
|
return {
|
|
@@ -103409,7 +103446,7 @@ class GatewayServer {
|
|
|
103409
103446
|
}
|
|
103410
103447
|
|
|
103411
103448
|
// src/config/manager.ts
|
|
103412
|
-
import { readFileSync } from "fs";
|
|
103449
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
103413
103450
|
|
|
103414
103451
|
// ../../node_modules/yaml/dist/index.js
|
|
103415
103452
|
var composer = require_composer();
|
|
@@ -107524,7 +107561,7 @@ class ConfigManager {
|
|
|
107524
107561
|
config = null;
|
|
107525
107562
|
loadFromFile(filePath) {
|
|
107526
107563
|
try {
|
|
107527
|
-
const fileContent =
|
|
107564
|
+
const fileContent = readFileSync2(filePath, "utf-8");
|
|
107528
107565
|
const processedContent = this.substituteEnvVars(fileContent);
|
|
107529
107566
|
let rawConfig;
|
|
107530
107567
|
if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
|
|
@@ -107612,7 +107649,7 @@ class ConfigManager {
|
|
|
107612
107649
|
}
|
|
107613
107650
|
const enabledServers = config3.servers.filter((s3) => s3.enabled);
|
|
107614
107651
|
if (enabledServers.length === 0) {
|
|
107615
|
-
console.
|
|
107652
|
+
console.error("[ConfigManager] No external servers configured. Native tools will be available.");
|
|
107616
107653
|
}
|
|
107617
107654
|
}
|
|
107618
107655
|
}
|
|
@@ -109186,7 +109223,7 @@ function createLogger(logLevel, useStderrOnly = false) {
|
|
|
109186
109223
|
if (useStderrOnly) {
|
|
109187
109224
|
console.error("[INFO]", ...args);
|
|
109188
109225
|
} else {
|
|
109189
|
-
console.
|
|
109226
|
+
console.error("[INFO]", ...args);
|
|
109190
109227
|
}
|
|
109191
109228
|
}
|
|
109192
109229
|
},
|
|
@@ -109217,7 +109254,7 @@ function createLogger(logLevel, useStderrOnly = false) {
|
|
|
109217
109254
|
};
|
|
109218
109255
|
}
|
|
109219
109256
|
function showHelp() {
|
|
109220
|
-
console.
|
|
109257
|
+
console.error(`
|
|
109221
109258
|
NextNext MCP Server - Sovereign Shopping Agent
|
|
109222
109259
|
|
|
109223
109260
|
USAGE:
|