mirror of
https://github.com/aljazceru/dvmcp.git
synced 2025-12-17 05:14:24 +01:00
refactor: logger implementation from discovery to commons package (#9)
This commit is contained in:
6
bun.lock
6
bun.lock
@@ -32,8 +32,12 @@
|
||||
},
|
||||
"packages/dvmcp-commons": {
|
||||
"name": "@dvmcp/commons",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/debug": "^4.1.12",
|
||||
"typescript": "^5.0.0",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "dvmcp",
|
||||
"scripts": {
|
||||
"start:mcp-dvm": "cd packages/mcp-dvm-bridge && bun start",
|
||||
"format": "prettier --write \"packages/**/*.{ts,tsx,js,jsx,json,md}\"",
|
||||
"publish:commons": "cd packages/dvmcp-commons && npm publish --access public",
|
||||
"publish:bridge": "cd packages/dvmcp-bridge && npm publish --access public",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dvmcp/bridge",
|
||||
"version": "0.1.19",
|
||||
"version": "0.1.20",
|
||||
"description": "Bridge connecting MCP servers to Nostr's DVM ecosystem",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
@@ -35,7 +35,7 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"nostr-tools": "^2.10.4",
|
||||
"yaml": "^2.7.0",
|
||||
"@dvmcp/commons": "^0.1.2"
|
||||
"@dvmcp/commons": "^0.1.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
TOOL_REQUEST_KIND,
|
||||
} from '@dvmcp/commons/constants';
|
||||
import type { Event } from 'nostr-tools/pure';
|
||||
import { loggerBridge } from '@dvmcp/commons/logger';
|
||||
|
||||
export const keyManager = createKeyManager(CONFIG.nostr.privateKey);
|
||||
|
||||
@@ -28,7 +29,7 @@ export class NostrAnnouncer {
|
||||
});
|
||||
|
||||
await this.relayHandler.publishEvent(event);
|
||||
console.log('Announced relay list metadata');
|
||||
loggerBridge('Announced relay list metadata');
|
||||
}
|
||||
|
||||
async announceService() {
|
||||
@@ -52,7 +53,7 @@ export class NostrAnnouncer {
|
||||
],
|
||||
});
|
||||
await this.relayHandler.publishEvent(event);
|
||||
console.log(`Announced service with ${tools.length} tools`);
|
||||
loggerBridge(`Announced service with ${tools.length} tools`);
|
||||
}
|
||||
|
||||
async updateAnnouncement() {
|
||||
@@ -82,7 +83,7 @@ export class NostrAnnouncer {
|
||||
});
|
||||
|
||||
await this.relayHandler.publishEvent(deletionEvent);
|
||||
console.log(`Published deletion event for service announcement`);
|
||||
loggerBridge(`Published deletion event for service announcement`);
|
||||
|
||||
return deletionEvent;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
TOOL_REQUEST_KIND,
|
||||
TOOL_RESPONSE_KIND,
|
||||
} from '@dvmcp/commons/constants';
|
||||
import { loggerBridge } from '@dvmcp/commons/logger';
|
||||
|
||||
export class DVMBridge {
|
||||
private mcpPool: MCPPool;
|
||||
@@ -17,8 +18,8 @@ export class DVMBridge {
|
||||
private isRunning: boolean = false;
|
||||
|
||||
constructor() {
|
||||
console.log('Initializing DVM Bridge...');
|
||||
console.log('public key:', keyManager.getPublicKey());
|
||||
loggerBridge('Initializing DVM Bridge...');
|
||||
loggerBridge('public key:', keyManager.getPublicKey());
|
||||
this.mcpPool = new MCPPool(CONFIG.mcp.servers);
|
||||
this.relayHandler = relayHandler;
|
||||
this.nostrAnnouncer = new NostrAnnouncer(this.mcpPool);
|
||||
@@ -36,21 +37,21 @@ export class DVMBridge {
|
||||
|
||||
async start() {
|
||||
if (this.isRunning) {
|
||||
console.log('Bridge is already running');
|
||||
loggerBridge('Bridge is already running');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('Connecting to MCP servers...');
|
||||
loggerBridge('Connecting to MCP servers...');
|
||||
await this.mcpPool.connect();
|
||||
|
||||
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();
|
||||
|
||||
console.log('Setting up request handlers...');
|
||||
loggerBridge('Setting up request handlers...');
|
||||
const publicKey = keyManager.getPublicKey();
|
||||
this.relayHandler.subscribeToRequests(this.handleRequest.bind(this), {
|
||||
kinds: [TOOL_REQUEST_KIND],
|
||||
@@ -59,7 +60,7 @@ export class DVMBridge {
|
||||
});
|
||||
|
||||
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) {
|
||||
console.error('Failed to start DVM Bridge:', error);
|
||||
throw error;
|
||||
@@ -71,12 +72,12 @@ export class DVMBridge {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Stopping DVM Bridge...');
|
||||
loggerBridge('Stopping DVM Bridge...');
|
||||
try {
|
||||
await this.mcpPool.disconnect();
|
||||
this.relayHandler.cleanup();
|
||||
this.isRunning = false;
|
||||
console.log('DVM Bridge stopped successfully');
|
||||
loggerBridge('DVM Bridge stopped successfully');
|
||||
} catch (error) {
|
||||
console.error('Error stopping DVM Bridge:', error);
|
||||
throw error;
|
||||
@@ -89,11 +90,11 @@ export class DVMBridge {
|
||||
* @returns The deletion event that was published
|
||||
*/
|
||||
async deleteAnnouncement(reason?: string) {
|
||||
console.log('Deleting service announcement from relays...');
|
||||
loggerBridge('Deleting service announcement from relays...');
|
||||
try {
|
||||
const deletionEvent =
|
||||
await this.nostrAnnouncer.deleteAnnouncement(reason);
|
||||
console.log('Service announcement deleted successfully');
|
||||
loggerBridge('Service announcement deleted successfully');
|
||||
return deletionEvent;
|
||||
} catch (error) {
|
||||
console.error('Error deleting service announcement:', error);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
||||
import { CONFIG } from './config';
|
||||
import type { MCPServerConfig } from './types';
|
||||
import { loggerBridge } from '@dvmcp/commons/logger';
|
||||
|
||||
export class MCPClientHandler {
|
||||
private client: Client;
|
||||
@@ -29,7 +30,7 @@ export class MCPClientHandler {
|
||||
|
||||
async connect() {
|
||||
await this.client.connect(this.transport);
|
||||
console.log('Connected to MCP server');
|
||||
loggerBridge('Connected to MCP server');
|
||||
}
|
||||
|
||||
async listTools() {
|
||||
|
||||
7
packages/dvmcp-commons/logger.ts
Normal file
7
packages/dvmcp-commons/logger.ts
Normal 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 };
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dvmcp/commons",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"description": "Shared utilities for DVMCP packages",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
@@ -18,7 +18,11 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
"typescript": "^5.0.0",
|
||||
"@types/debug": "^4.1.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dvmcp/discovery",
|
||||
"version": "0.1.18",
|
||||
"version": "0.1.19",
|
||||
"description": "Discovery service for MCP tools in the Nostr DVM ecosystem",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
@@ -34,8 +34,7 @@
|
||||
"@modelcontextprotocol/sdk": "^1.5.0",
|
||||
"nostr-tools": "^2.10.4",
|
||||
"yaml": "^2.7.0",
|
||||
"@dvmcp/commons": "^0.1.2",
|
||||
"debug": "^4.4.0"
|
||||
"@dvmcp/commons": "^0.1.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Event, Filter } from 'nostr-tools';
|
||||
import { RelayHandler } from '@dvmcp/commons/nostr/relay-handler';
|
||||
import { DVM_ANNOUNCEMENT_KIND } from '@dvmcp/commons/constants';
|
||||
import type { NaddrData, NprofileData } from './nip19-utils';
|
||||
import logger from './logger';
|
||||
import { loggerDiscovery } from '@dvmcp/commons/logger';
|
||||
|
||||
export interface DVMAnnouncement {
|
||||
name: string;
|
||||
@@ -20,7 +20,7 @@ async function fetchAnnouncement(
|
||||
|
||||
try {
|
||||
// Query for the announcement event
|
||||
logger('Querying for announcement event:', filter);
|
||||
loggerDiscovery('Querying for announcement event:', filter);
|
||||
const events = await relayHandler.queryEvents(filter);
|
||||
|
||||
if (events.length === 0) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { ToolRegistry } from './tool-registry';
|
||||
import { ToolExecutor } from './tool-executor';
|
||||
import type { DVMAnnouncement } from './direct-discovery';
|
||||
import logger from './logger';
|
||||
import { loggerDiscovery } from '@dvmcp/commons/logger';
|
||||
|
||||
export class DiscoveryServer {
|
||||
private mcpServer: McpServer;
|
||||
@@ -64,7 +64,7 @@ export class DiscoveryServer {
|
||||
private async handleDVMAnnouncement(event: Event) {
|
||||
try {
|
||||
if (!this.isAllowedDVM(event.pubkey)) {
|
||||
logger('DVM not in whitelist:', event.pubkey);
|
||||
loggerDiscovery('DVM not in whitelist:', event.pubkey);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ export class DiscoveryServer {
|
||||
pubkey: string,
|
||||
announcement: DVMAnnouncement
|
||||
) {
|
||||
logger('Starting discovery server with direct server tools...');
|
||||
loggerDiscovery('Starting discovery server with direct server tools...');
|
||||
|
||||
if (!announcement?.tools) {
|
||||
console.error('No tools found in server announcement');
|
||||
@@ -113,25 +113,27 @@ export class DiscoveryServer {
|
||||
|
||||
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
|
||||
const transport = new StdioServerTransport();
|
||||
await this.mcpServer.connect(transport);
|
||||
|
||||
logger('DVMCP Discovery Server started');
|
||||
loggerDiscovery('DVMCP Discovery Server started');
|
||||
}
|
||||
|
||||
public async start() {
|
||||
logger('Starting discovery server...');
|
||||
loggerDiscovery('Starting discovery server...');
|
||||
|
||||
await this.startDiscovery();
|
||||
logger(`Discovered ${this.toolRegistry.listTools().length} tools`);
|
||||
loggerDiscovery(`Discovered ${this.toolRegistry.listTools().length} tools`);
|
||||
|
||||
const transport = new StdioServerTransport();
|
||||
await this.mcpServer.connect(transport);
|
||||
|
||||
logger('DVMCP Discovery Server started');
|
||||
loggerDiscovery('DVMCP Discovery Server started');
|
||||
}
|
||||
|
||||
public async cleanup(): Promise<void> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { nip19 } from 'nostr-tools';
|
||||
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
|
||||
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
|
||||
const profileData = data as NprofileData;
|
||||
if (!profileData.relays || profileData.relays.length === 0) {
|
||||
logger(
|
||||
loggerDiscovery(
|
||||
`No relay hints in nprofile, using fallback relay: ${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
|
||||
const addrData = data as NaddrData;
|
||||
if (!addrData.relays || addrData.relays.length === 0) {
|
||||
logger(
|
||||
loggerDiscovery(
|
||||
`No relay hints in naddr, using fallback relay: ${DEFAULT_FALLBACK_RELAY}`
|
||||
);
|
||||
addrData.relays = [DEFAULT_FALLBACK_RELAY];
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
TOOL_RESPONSE_KIND,
|
||||
DVM_NOTICE_KIND,
|
||||
} from '@dvmcp/commons/constants';
|
||||
import logger from './logger';
|
||||
import { loggerDiscovery } from '@dvmcp/commons/logger';
|
||||
|
||||
interface ExecutionContext {
|
||||
timeoutId: ReturnType<typeof setTimeout>;
|
||||
@@ -66,7 +66,7 @@ export class ToolExecutor {
|
||||
|
||||
private createExecutionContext(executionId: string): ExecutionContext {
|
||||
const timeoutId = setTimeout(() => {
|
||||
logger('Execution timeout for:', executionId);
|
||||
loggerDiscovery('Execution timeout for:', executionId);
|
||||
this.cleanupExecution(executionId);
|
||||
}, ToolExecutor.EXECUTION_TIMEOUT);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { type Tool } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { ToolSchema } from '@modelcontextprotocol/sdk/types.js';
|
||||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
import { z } from 'zod';
|
||||
import logger from './logger';
|
||||
import { loggerDiscovery } from '@dvmcp/commons/logger';
|
||||
|
||||
export class ToolRegistry {
|
||||
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) {
|
||||
console.error('Error registering tool:', toolId, error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user