@thorium-dev-group/x402-mcp-extension
Version:
X402-MCP Protocol Extension
151 lines • 7.04 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.X402MCPServer = void 0;
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
const handlers_1 = require("./services/handlers");
const PaymentOrchestrator_1 = require("./services/payments/PaymentOrchestrator");
const services_1 = require("../shared/services");
class X402MCPServer extends mcp_js_1.McpServer {
options;
paymentOrchestrator;
logger;
handlerClasses = [];
constructor(options) {
super({
name: options.name,
version: options.version,
capabilities: {
experimental: {
x402: {
paymentsEnabled: true,
},
},
},
});
this.options = options;
const loggerFactory = options.loggerFactory || new services_1.ConsoleLoggerFactory();
this.logger = loggerFactory.createLogger(X402MCPServer.name, {
sessionId: options.sessionId,
});
this.paymentOrchestrator = new PaymentOrchestrator_1.PaymentOrchestrator({
payTo: options.x402Config.payTo,
network: options.x402Config.network,
facilitator: options.x402Config.facilitator,
loggerFactory: loggerFactory,
});
}
registerHandlers(...handlerClasses) {
this.handlerClasses.push(...handlerClasses);
this.logger.info('Registered handler classes', {
count: handlerClasses.length,
totalHandlers: this.handlerClasses.length
});
}
async connect(transport) {
this.logger.info('X402MCPServer connecting to transport');
await this.registerSessionHandlers();
this.logger.info('Session handlers registered, connecting to transport');
return super.connect(transport);
}
async registerSessionHandlers() {
this.logger.info('Creating session handlers', {
handlerClasses: this.handlerClasses.length
});
if (this.handlerClasses.length === 0) {
this.logger.warn('No handler classes registered');
return;
}
const sessionHandlers = handlers_1.HandlerRegistry.createSessionHandlers(this.handlerClasses);
this.logger.info('Session handlers created', {
tools: sessionHandlers.tools.length,
prompts: sessionHandlers.prompts.length,
resources: sessionHandlers.resources.length,
resourceTemplates: sessionHandlers.resourceTemplates.length
});
const context = {
x402Config: {
payTo: this.options.x402Config.payTo,
network: this.options.x402Config.network,
baseUrl: this.options.x402Config.baseMCPServerDomain,
},
paymentOrchestrator: this.paymentOrchestrator,
logger: this.logger,
};
for (const toolInfo of sessionHandlers.tools) {
const wrappedTool = handlers_1.HandlerWrapperFactory.createToolWrapper(toolInfo, context);
const toolOptions = toolInfo.options;
let description = toolOptions.description || toolInfo.name;
if (toolInfo.paymentOptions) {
description += ` (fee: ${toolInfo.paymentOptions.amount} USD)`;
}
let annotations = toolOptions.annotations || {};
if (toolInfo.paymentOptions) {
annotations = {
...annotations,
feeUSD: toolInfo.paymentOptions.amount,
};
}
if (toolOptions.inputSchema) {
this.tool(toolInfo.name, description, toolOptions.inputSchema, annotations, wrappedTool);
}
else {
this.tool(toolInfo.name, description, annotations, wrappedTool);
}
this.logger.debug('Registered tool', { name: toolInfo.name });
}
for (const promptInfo of sessionHandlers.prompts) {
const wrappedPrompt = handlers_1.HandlerWrapperFactory.createPromptWrapper(promptInfo, context);
const promptOptions = promptInfo.options;
let description = promptOptions.description || promptInfo.name;
if (promptInfo.paymentOptions) {
description += ` (fee: ${promptInfo.paymentOptions.amount} USD)`;
}
if (promptOptions.argsSchema) {
this.prompt(promptInfo.name, description, promptOptions.argsSchema, wrappedPrompt);
}
else {
this.prompt(promptInfo.name, description, wrappedPrompt);
}
this.logger.debug('Registered prompt', { name: promptInfo.name });
}
for (const resourceInfo of sessionHandlers.resources) {
const wrappedResource = handlers_1.HandlerWrapperFactory.createResourceWrapper(resourceInfo, context);
const resourceOptions = resourceInfo.options;
let description = resourceOptions.description || resourceInfo.name;
if (resourceInfo.paymentOptions) {
description += ` (fee: ${resourceInfo.paymentOptions.amount} USD)`;
}
this.resource(resourceInfo.name, resourceOptions.uri, {
description: description,
mimeType: resourceOptions.mimeType,
title: resourceOptions.title,
}, wrappedResource);
this.logger.debug('Registered resource', { name: resourceInfo.name });
}
for (const templateInfo of sessionHandlers.resourceTemplates) {
const wrappedTemplate = handlers_1.HandlerWrapperFactory.createResourceTemplateWrapper(templateInfo, context);
const templateOptions = templateInfo.options;
let description = templateOptions.description || templateInfo.name;
if (templateInfo.paymentOptions) {
description += ` (fee: ${templateInfo.paymentOptions.amount} USD)`;
}
const { ResourceTemplate } = require('@modelcontextprotocol/sdk/server/mcp.js');
const template = new ResourceTemplate(templateOptions.template, {
list: templateOptions.listCallback,
complete: templateOptions.completeCallbacks,
});
this.resource(templateInfo.name, template, {
description: description,
mimeType: templateOptions.mimeType,
title: templateOptions.title,
}, wrappedTemplate);
this.logger.debug('Registered resource template', { name: templateInfo.name });
}
this.logger.info('Session handlers registration complete', {
totalHandlers: sessionHandlers.tools.length + sessionHandlers.prompts.length +
sessionHandlers.resources.length + sessionHandlers.resourceTemplates.length
});
}
}
exports.X402MCPServer = X402MCPServer;
//# sourceMappingURL=x402MCPServer.js.map