refactor: logger implementation from discovery to commons package (#9)

This commit is contained in:
gzuuus
2025-03-26 22:51:16 +01:00
committed by GitHub
parent 07e60bb4ba
commit b238d38c5a
14 changed files with 60 additions and 42 deletions

View File

@@ -32,8 +32,12 @@
}, },
"packages/dvmcp-commons": { "packages/dvmcp-commons": {
"name": "@dvmcp/commons", "name": "@dvmcp/commons",
"version": "0.1.2", "version": "0.1.3",
"dependencies": {
"debug": "^4.4.0",
},
"peerDependencies": { "peerDependencies": {
"@types/debug": "^4.1.12",
"typescript": "^5.0.0", "typescript": "^5.0.0",
}, },
}, },

View File

@@ -1,7 +1,6 @@
{ {
"name": "dvmcp", "name": "dvmcp",
"scripts": { "scripts": {
"start:mcp-dvm": "cd packages/mcp-dvm-bridge && bun start",
"format": "prettier --write \"packages/**/*.{ts,tsx,js,jsx,json,md}\"", "format": "prettier --write \"packages/**/*.{ts,tsx,js,jsx,json,md}\"",
"publish:commons": "cd packages/dvmcp-commons && npm publish --access public", "publish:commons": "cd packages/dvmcp-commons && npm publish --access public",
"publish:bridge": "cd packages/dvmcp-bridge && npm publish --access public", "publish:bridge": "cd packages/dvmcp-bridge && npm publish --access public",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@dvmcp/bridge", "name": "@dvmcp/bridge",
"version": "0.1.19", "version": "0.1.20",
"description": "Bridge connecting MCP servers to Nostr's DVM ecosystem", "description": "Bridge connecting MCP servers to Nostr's DVM ecosystem",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
@@ -35,7 +35,7 @@
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"nostr-tools": "^2.10.4", "nostr-tools": "^2.10.4",
"yaml": "^2.7.0", "yaml": "^2.7.0",
"@dvmcp/commons": "^0.1.2" "@dvmcp/commons": "^0.1.3"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@@ -8,6 +8,7 @@ import {
TOOL_REQUEST_KIND, TOOL_REQUEST_KIND,
} from '@dvmcp/commons/constants'; } from '@dvmcp/commons/constants';
import type { Event } from 'nostr-tools/pure'; import type { Event } from 'nostr-tools/pure';
import { loggerBridge } from '@dvmcp/commons/logger';
export const keyManager = createKeyManager(CONFIG.nostr.privateKey); export const keyManager = createKeyManager(CONFIG.nostr.privateKey);
@@ -28,7 +29,7 @@ export class NostrAnnouncer {
}); });
await this.relayHandler.publishEvent(event); await this.relayHandler.publishEvent(event);
console.log('Announced relay list metadata'); loggerBridge('Announced relay list metadata');
} }
async announceService() { async announceService() {
@@ -52,7 +53,7 @@ export class NostrAnnouncer {
], ],
}); });
await this.relayHandler.publishEvent(event); await this.relayHandler.publishEvent(event);
console.log(`Announced service with ${tools.length} tools`); loggerBridge(`Announced service with ${tools.length} tools`);
} }
async updateAnnouncement() { async updateAnnouncement() {
@@ -82,7 +83,7 @@ export class NostrAnnouncer {
}); });
await this.relayHandler.publishEvent(deletionEvent); await this.relayHandler.publishEvent(deletionEvent);
console.log(`Published deletion event for service announcement`); loggerBridge(`Published deletion event for service announcement`);
return deletionEvent; return deletionEvent;
} }

View File

@@ -9,6 +9,7 @@ import {
TOOL_REQUEST_KIND, TOOL_REQUEST_KIND,
TOOL_RESPONSE_KIND, TOOL_RESPONSE_KIND,
} from '@dvmcp/commons/constants'; } from '@dvmcp/commons/constants';
import { loggerBridge } from '@dvmcp/commons/logger';
export class DVMBridge { export class DVMBridge {
private mcpPool: MCPPool; private mcpPool: MCPPool;
@@ -17,8 +18,8 @@ export class DVMBridge {
private isRunning: boolean = false; private isRunning: boolean = false;
constructor() { constructor() {
console.log('Initializing DVM Bridge...'); loggerBridge('Initializing DVM Bridge...');
console.log('public key:', keyManager.getPublicKey()); loggerBridge('public key:', keyManager.getPublicKey());
this.mcpPool = new MCPPool(CONFIG.mcp.servers); this.mcpPool = new MCPPool(CONFIG.mcp.servers);
this.relayHandler = relayHandler; this.relayHandler = relayHandler;
this.nostrAnnouncer = new NostrAnnouncer(this.mcpPool); this.nostrAnnouncer = new NostrAnnouncer(this.mcpPool);
@@ -36,21 +37,21 @@ export class DVMBridge {
async start() { async start() {
if (this.isRunning) { if (this.isRunning) {
console.log('Bridge is already running'); loggerBridge('Bridge is already running');
return; return;
} }
try { try {
console.log('Connecting to MCP servers...'); loggerBridge('Connecting to MCP servers...');
await this.mcpPool.connect(); await this.mcpPool.connect();
const tools = await this.mcpPool.listTools(); const tools = await this.mcpPool.listTools();
console.log(`Available MCP tools across all servers: ${tools.length}`); loggerBridge(`Available MCP tools across all servers: ${tools.length}`);
console.log('Announcing service to Nostr network...'); loggerBridge('Announcing service to Nostr network...');
await this.nostrAnnouncer.updateAnnouncement(); await this.nostrAnnouncer.updateAnnouncement();
console.log('Setting up request handlers...'); loggerBridge('Setting up request handlers...');
const publicKey = keyManager.getPublicKey(); const publicKey = keyManager.getPublicKey();
this.relayHandler.subscribeToRequests(this.handleRequest.bind(this), { this.relayHandler.subscribeToRequests(this.handleRequest.bind(this), {
kinds: [TOOL_REQUEST_KIND], kinds: [TOOL_REQUEST_KIND],
@@ -59,7 +60,7 @@ export class DVMBridge {
}); });
this.isRunning = true; this.isRunning = true;
console.log('DVM Bridge is now running and ready to handle requests'); loggerBridge('DVM Bridge is now running and ready to handle requests');
} catch (error) { } catch (error) {
console.error('Failed to start DVM Bridge:', error); console.error('Failed to start DVM Bridge:', error);
throw error; throw error;
@@ -71,12 +72,12 @@ export class DVMBridge {
return; return;
} }
console.log('Stopping DVM Bridge...'); loggerBridge('Stopping DVM Bridge...');
try { try {
await this.mcpPool.disconnect(); await this.mcpPool.disconnect();
this.relayHandler.cleanup(); this.relayHandler.cleanup();
this.isRunning = false; this.isRunning = false;
console.log('DVM Bridge stopped successfully'); loggerBridge('DVM Bridge stopped successfully');
} catch (error) { } catch (error) {
console.error('Error stopping DVM Bridge:', error); console.error('Error stopping DVM Bridge:', error);
throw error; throw error;
@@ -89,11 +90,11 @@ export class DVMBridge {
* @returns The deletion event that was published * @returns The deletion event that was published
*/ */
async deleteAnnouncement(reason?: string) { async deleteAnnouncement(reason?: string) {
console.log('Deleting service announcement from relays...'); loggerBridge('Deleting service announcement from relays...');
try { try {
const deletionEvent = const deletionEvent =
await this.nostrAnnouncer.deleteAnnouncement(reason); await this.nostrAnnouncer.deleteAnnouncement(reason);
console.log('Service announcement deleted successfully'); loggerBridge('Service announcement deleted successfully');
return deletionEvent; return deletionEvent;
} catch (error) { } catch (error) {
console.error('Error deleting service announcement:', error); console.error('Error deleting service announcement:', error);

View File

@@ -2,6 +2,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CONFIG } from './config'; import { CONFIG } from './config';
import type { MCPServerConfig } from './types'; import type { MCPServerConfig } from './types';
import { loggerBridge } from '@dvmcp/commons/logger';
export class MCPClientHandler { export class MCPClientHandler {
private client: Client; private client: Client;
@@ -29,7 +30,7 @@ export class MCPClientHandler {
async connect() { async connect() {
await this.client.connect(this.transport); await this.client.connect(this.transport);
console.log('Connected to MCP server'); loggerBridge('Connected to MCP server');
} }
async listTools() { async listTools() {

View File

@@ -0,0 +1,7 @@
import debug from 'debug';
const logger = debug('dvmcp');
const loggerBridge = debug('dvmcp:bridge');
const loggerDiscovery = debug('dvmcp:discovery');
export { logger, loggerBridge, loggerDiscovery };

View File

@@ -1,6 +1,6 @@
{ {
"name": "@dvmcp/commons", "name": "@dvmcp/commons",
"version": "0.1.2", "version": "0.1.3",
"description": "Shared utilities for DVMCP packages", "description": "Shared utilities for DVMCP packages",
"type": "module", "type": "module",
"exports": { "exports": {
@@ -18,7 +18,11 @@
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^5.0.0" "typescript": "^5.0.0",
"@types/debug": "^4.1.12"
},
"dependencies": {
"debug": "^4.4.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@dvmcp/discovery", "name": "@dvmcp/discovery",
"version": "0.1.18", "version": "0.1.19",
"description": "Discovery service for MCP tools in the Nostr DVM ecosystem", "description": "Discovery service for MCP tools in the Nostr DVM ecosystem",
"module": "index.ts", "module": "index.ts",
"type": "module", "type": "module",
@@ -34,8 +34,7 @@
"@modelcontextprotocol/sdk": "^1.5.0", "@modelcontextprotocol/sdk": "^1.5.0",
"nostr-tools": "^2.10.4", "nostr-tools": "^2.10.4",
"yaml": "^2.7.0", "yaml": "^2.7.0",
"@dvmcp/commons": "^0.1.2", "@dvmcp/commons": "^0.1.3"
"debug": "^4.4.0"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"

View File

@@ -2,7 +2,7 @@ import type { Event, Filter } from 'nostr-tools';
import { RelayHandler } from '@dvmcp/commons/nostr/relay-handler'; import { RelayHandler } from '@dvmcp/commons/nostr/relay-handler';
import { DVM_ANNOUNCEMENT_KIND } from '@dvmcp/commons/constants'; import { DVM_ANNOUNCEMENT_KIND } from '@dvmcp/commons/constants';
import type { NaddrData, NprofileData } from './nip19-utils'; import type { NaddrData, NprofileData } from './nip19-utils';
import logger from './logger'; import { loggerDiscovery } from '@dvmcp/commons/logger';
export interface DVMAnnouncement { export interface DVMAnnouncement {
name: string; name: string;
@@ -20,7 +20,7 @@ async function fetchAnnouncement(
try { try {
// Query for the announcement event // Query for the announcement event
logger('Querying for announcement event:', filter); loggerDiscovery('Querying for announcement event:', filter);
const events = await relayHandler.queryEvents(filter); const events = await relayHandler.queryEvents(filter);
if (events.length === 0) { if (events.length === 0) {

View File

@@ -9,7 +9,7 @@ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
import { ToolRegistry } from './tool-registry'; import { ToolRegistry } from './tool-registry';
import { ToolExecutor } from './tool-executor'; import { ToolExecutor } from './tool-executor';
import type { DVMAnnouncement } from './direct-discovery'; import type { DVMAnnouncement } from './direct-discovery';
import logger from './logger'; import { loggerDiscovery } from '@dvmcp/commons/logger';
export class DiscoveryServer { export class DiscoveryServer {
private mcpServer: McpServer; private mcpServer: McpServer;
@@ -64,7 +64,7 @@ export class DiscoveryServer {
private async handleDVMAnnouncement(event: Event) { private async handleDVMAnnouncement(event: Event) {
try { try {
if (!this.isAllowedDVM(event.pubkey)) { if (!this.isAllowedDVM(event.pubkey)) {
logger('DVM not in whitelist:', event.pubkey); loggerDiscovery('DVM not in whitelist:', event.pubkey);
return; return;
} }
@@ -104,7 +104,7 @@ export class DiscoveryServer {
pubkey: string, pubkey: string,
announcement: DVMAnnouncement announcement: DVMAnnouncement
) { ) {
logger('Starting discovery server with direct server tools...'); loggerDiscovery('Starting discovery server with direct server tools...');
if (!announcement?.tools) { if (!announcement?.tools) {
console.error('No tools found in server announcement'); console.error('No tools found in server announcement');
@@ -113,25 +113,27 @@ export class DiscoveryServer {
this.registerToolsFromAnnouncement(pubkey, announcement.tools); this.registerToolsFromAnnouncement(pubkey, announcement.tools);
logger(`Registered ${announcement.tools.length} tools from direct server`); loggerDiscovery(
`Registered ${announcement.tools.length} tools from direct server`
);
// Connect the MCP server // Connect the MCP server
const transport = new StdioServerTransport(); const transport = new StdioServerTransport();
await this.mcpServer.connect(transport); await this.mcpServer.connect(transport);
logger('DVMCP Discovery Server started'); loggerDiscovery('DVMCP Discovery Server started');
} }
public async start() { public async start() {
logger('Starting discovery server...'); loggerDiscovery('Starting discovery server...');
await this.startDiscovery(); await this.startDiscovery();
logger(`Discovered ${this.toolRegistry.listTools().length} tools`); loggerDiscovery(`Discovered ${this.toolRegistry.listTools().length} tools`);
const transport = new StdioServerTransport(); const transport = new StdioServerTransport();
await this.mcpServer.connect(transport); await this.mcpServer.connect(transport);
logger('DVMCP Discovery Server started'); loggerDiscovery('DVMCP Discovery Server started');
} }
public async cleanup(): Promise<void> { public async cleanup(): Promise<void> {

View File

@@ -1,6 +1,6 @@
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { DVM_ANNOUNCEMENT_KIND } from '@dvmcp/commons/constants'; import { DVM_ANNOUNCEMENT_KIND } from '@dvmcp/commons/constants';
import logger from './logger'; import { loggerDiscovery } from '@dvmcp/commons/logger';
// Default fallback relay when no relay hints are provided // Default fallback relay when no relay hints are provided
export const DEFAULT_FALLBACK_RELAY = 'wss://relay.dvmcp.fun'; export const DEFAULT_FALLBACK_RELAY = 'wss://relay.dvmcp.fun';
@@ -33,7 +33,7 @@ export function decodeNprofile(nprofileEntity: string): NprofileData | null {
// Ensure we have at least one relay by using the fallback if necessary // Ensure we have at least one relay by using the fallback if necessary
const profileData = data as NprofileData; const profileData = data as NprofileData;
if (!profileData.relays || profileData.relays.length === 0) { if (!profileData.relays || profileData.relays.length === 0) {
logger( loggerDiscovery(
`No relay hints in nprofile, using fallback relay: ${DEFAULT_FALLBACK_RELAY}` `No relay hints in nprofile, using fallback relay: ${DEFAULT_FALLBACK_RELAY}`
); );
profileData.relays = [DEFAULT_FALLBACK_RELAY]; profileData.relays = [DEFAULT_FALLBACK_RELAY];
@@ -68,7 +68,7 @@ export function decodeNaddr(naddrEntity: string): NaddrData | null {
// Ensure we have at least one relay by using the fallback if necessary // Ensure we have at least one relay by using the fallback if necessary
const addrData = data as NaddrData; const addrData = data as NaddrData;
if (!addrData.relays || addrData.relays.length === 0) { if (!addrData.relays || addrData.relays.length === 0) {
logger( loggerDiscovery(
`No relay hints in naddr, using fallback relay: ${DEFAULT_FALLBACK_RELAY}` `No relay hints in naddr, using fallback relay: ${DEFAULT_FALLBACK_RELAY}`
); );
addrData.relays = [DEFAULT_FALLBACK_RELAY]; addrData.relays = [DEFAULT_FALLBACK_RELAY];

View File

@@ -8,7 +8,7 @@ import {
TOOL_RESPONSE_KIND, TOOL_RESPONSE_KIND,
DVM_NOTICE_KIND, DVM_NOTICE_KIND,
} from '@dvmcp/commons/constants'; } from '@dvmcp/commons/constants';
import logger from './logger'; import { loggerDiscovery } from '@dvmcp/commons/logger';
interface ExecutionContext { interface ExecutionContext {
timeoutId: ReturnType<typeof setTimeout>; timeoutId: ReturnType<typeof setTimeout>;
@@ -66,7 +66,7 @@ export class ToolExecutor {
private createExecutionContext(executionId: string): ExecutionContext { private createExecutionContext(executionId: string): ExecutionContext {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
logger('Execution timeout for:', executionId); loggerDiscovery('Execution timeout for:', executionId);
this.cleanupExecution(executionId); this.cleanupExecution(executionId);
}, ToolExecutor.EXECUTION_TIMEOUT); }, ToolExecutor.EXECUTION_TIMEOUT);

View File

@@ -2,7 +2,7 @@ import { type Tool } from '@modelcontextprotocol/sdk/types.js';
import { ToolSchema } from '@modelcontextprotocol/sdk/types.js'; import { ToolSchema } from '@modelcontextprotocol/sdk/types.js';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod'; import { z } from 'zod';
import logger from './logger'; import { loggerDiscovery } from '@dvmcp/commons/logger';
export class ToolRegistry { export class ToolRegistry {
private discoveredTools: Map<string, { tool: Tool; providerPubkey: string }> = private discoveredTools: Map<string, { tool: Tool; providerPubkey: string }> =
@@ -73,7 +73,7 @@ export class ToolRegistry {
} }
} }
); );
logger('Tool registered successfully:', toolId); loggerDiscovery('Tool registered successfully:', toolId);
} catch (error) { } catch (error) {
console.error('Error registering tool:', toolId, error); console.error('Error registering tool:', toolId, error);
} }