@mainwp/mcp 1.0.0-beta.1

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.
Files changed (49) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +1034 -0
  3. package/dist/abilities.d.ts +144 -0
  4. package/dist/abilities.d.ts.map +1 -0
  5. package/dist/abilities.js +529 -0
  6. package/dist/abilities.js.map +1 -0
  7. package/dist/config.d.ts +135 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +405 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/confirmation-responses.d.ts +44 -0
  12. package/dist/confirmation-responses.d.ts.map +1 -0
  13. package/dist/confirmation-responses.js +120 -0
  14. package/dist/confirmation-responses.js.map +1 -0
  15. package/dist/errors.d.ts +118 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +206 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/index.d.ts +17 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +506 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/logging.d.ts +34 -0
  24. package/dist/logging.d.ts.map +1 -0
  25. package/dist/logging.js +74 -0
  26. package/dist/logging.js.map +1 -0
  27. package/dist/naming.d.ts +23 -0
  28. package/dist/naming.d.ts.map +1 -0
  29. package/dist/naming.js +37 -0
  30. package/dist/naming.js.map +1 -0
  31. package/dist/prompts.d.ts +22 -0
  32. package/dist/prompts.d.ts.map +1 -0
  33. package/dist/prompts.js +414 -0
  34. package/dist/prompts.js.map +1 -0
  35. package/dist/retry.d.ts +77 -0
  36. package/dist/retry.d.ts.map +1 -0
  37. package/dist/retry.js +206 -0
  38. package/dist/retry.js.map +1 -0
  39. package/dist/security.d.ts +41 -0
  40. package/dist/security.d.ts.map +1 -0
  41. package/dist/security.js +154 -0
  42. package/dist/security.js.map +1 -0
  43. package/dist/tools.d.ts +82 -0
  44. package/dist/tools.d.ts.map +1 -0
  45. package/dist/tools.js +861 -0
  46. package/dist/tools.js.map +1 -0
  47. package/package.json +73 -0
  48. package/settings.example.json +30 -0
  49. package/settings.schema.json +129 -0
package/dist/index.js ADDED
@@ -0,0 +1,506 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MainWP MCP Server
4
+ *
5
+ * Model Context Protocol server that exposes MainWP Dashboard abilities
6
+ * as MCP tools for AI assistants like Claude.
7
+ *
8
+ * Usage:
9
+ * MAINWP_URL=https://dashboard.local MAINWP_TOKEN=xxx node dist/index.js
10
+ *
11
+ * Environment Variables:
12
+ * - MAINWP_URL: Base URL of MainWP Dashboard (required)
13
+ * - MAINWP_TOKEN: Bearer token for authentication (required)
14
+ * - MAINWP_SKIP_SSL_VERIFY: Set to "true" to skip SSL verification (optional)
15
+ */
16
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
17
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
18
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, CompleteRequestSchema, ListResourceTemplatesRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
19
+ import { loadConfig, formatJson } from './config.js';
20
+ import { getTools, executeTool, toolNameToAbilityName, getSessionDataUsage } from './tools.js';
21
+ import { fetchAbilities, fetchCategories, clearCache, onCacheRefresh, executeAbility, initRateLimiter, getAbility, generateHelpDocument, generateToolHelp, } from './abilities.js';
22
+ import { getPromptList, getPrompt, getPromptArgumentCompletions } from './prompts.js';
23
+ import { createLogger, createStderrLogger } from './logging.js';
24
+ import { sanitizeError, isValidId, validateInput } from './security.js';
25
+ import { formatErrorResponse, McpErrorFactory, McpError } from './errors.js';
26
+ // Server metadata
27
+ const SERVER_NAME = 'mainwp-mcp';
28
+ const SERVER_VERSION = '1.0.0-beta.1';
29
+ // Completion limits
30
+ const MAX_COMPLETION_SUGGESTIONS = 20;
31
+ /**
32
+ * Validate and parse a resource URI.
33
+ * Only allows known URI patterns to prevent injection attacks.
34
+ * Decodes URL-encoded characters before validation.
35
+ */
36
+ function validateResourceUri(uri) {
37
+ // Decode URI to handle URL-encoded characters (e.g., %20, %2F)
38
+ let decodedUri;
39
+ try {
40
+ decodedUri = decodeURIComponent(uri);
41
+ }
42
+ catch (error) {
43
+ // Handle malformed URIs (invalid percent-encoding)
44
+ throw McpErrorFactory.invalidParams('Malformed URI: invalid percent-encoding', {
45
+ uri,
46
+ error: error instanceof Error ? error.message : String(error),
47
+ });
48
+ }
49
+ const staticUris = [
50
+ 'mainwp://abilities',
51
+ 'mainwp://categories',
52
+ 'mainwp://status',
53
+ 'mainwp://help',
54
+ ];
55
+ if (staticUris.includes(decodedUri)) {
56
+ return { type: decodedUri.replace('mainwp://', '') };
57
+ }
58
+ // Match mainwp://site/{id} pattern with strict numeric ID
59
+ const siteMatch = decodedUri.match(/^mainwp:\/\/site\/(\d+)$/);
60
+ if (siteMatch) {
61
+ const siteId = parseInt(siteMatch[1], 10);
62
+ if (siteId < 1 || siteId > Number.MAX_SAFE_INTEGER) {
63
+ throw McpErrorFactory.invalidParams('Invalid site ID: must be between 1 and ' + Number.MAX_SAFE_INTEGER, { uri, siteId });
64
+ }
65
+ return { type: 'site', params: { site_id: siteId } };
66
+ }
67
+ // Match mainwp://help/tool/{tool_name} pattern (lowercase only, matches tool name format)
68
+ const toolHelpMatch = decodedUri.match(/^mainwp:\/\/help\/tool\/([a-z0-9_]+)$/);
69
+ if (toolHelpMatch) {
70
+ return { type: 'tool-help', params: { tool_name: toolHelpMatch[1] } };
71
+ }
72
+ throw McpErrorFactory.resourceNotFound(uri);
73
+ }
74
+ /**
75
+ * Create and configure the MCP server
76
+ */
77
+ async function createServer(config) {
78
+ const server = new Server({
79
+ name: SERVER_NAME,
80
+ version: SERVER_VERSION,
81
+ }, {
82
+ capabilities: {
83
+ tools: { listChanged: true },
84
+ resources: { listChanged: true },
85
+ prompts: { listChanged: true },
86
+ logging: {},
87
+ completions: {},
88
+ },
89
+ });
90
+ // Create structured logger
91
+ const logger = createLogger(server);
92
+ // Handler: List available tools (derived from abilities)
93
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
94
+ try {
95
+ const tools = await getTools(config, logger);
96
+ return { tools };
97
+ }
98
+ catch (error) {
99
+ logger.error('Error listing tools', {
100
+ error: error instanceof Error ? error.message : String(error),
101
+ });
102
+ return { tools: [] };
103
+ }
104
+ });
105
+ // Handler: Execute a tool call
106
+ server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
107
+ const { name, arguments: args } = request.params;
108
+ try {
109
+ // Pass abort signal for cancellation support
110
+ const content = await executeTool(config, name, args ?? {}, logger, { signal: extra.signal });
111
+ return { content };
112
+ }
113
+ catch (error) {
114
+ return {
115
+ content: [
116
+ {
117
+ type: 'text',
118
+ text: formatErrorResponse(error, sanitizeError),
119
+ },
120
+ ],
121
+ isError: true,
122
+ };
123
+ }
124
+ });
125
+ // Handler: List available resources (abilities info, categories, help)
126
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
127
+ return {
128
+ resources: [
129
+ {
130
+ uri: 'mainwp://abilities',
131
+ name: 'MainWP Abilities',
132
+ description: 'List of all available MainWP abilities with their schemas',
133
+ mimeType: 'application/json',
134
+ },
135
+ {
136
+ uri: 'mainwp://categories',
137
+ name: 'MainWP Categories',
138
+ description: 'List of ability categories',
139
+ mimeType: 'application/json',
140
+ },
141
+ {
142
+ uri: 'mainwp://status',
143
+ name: 'Connection Status',
144
+ description: 'Current connection status to MainWP Dashboard',
145
+ mimeType: 'application/json',
146
+ },
147
+ {
148
+ uri: 'mainwp://help',
149
+ name: 'MainWP MCP Help',
150
+ description: 'Tool documentation, safety conventions (dry_run, confirm), and usage guides',
151
+ mimeType: 'application/json',
152
+ },
153
+ ],
154
+ };
155
+ });
156
+ // Handler: Read a resource
157
+ // URI Handling Convention:
158
+ // - Static URIs (mainwp://abilities, mainwp://categories, mainwp://status, mainwp://help)
159
+ // use direct equality checks for performance.
160
+ // - Dynamic/parameterized URIs (mainwp://site/{id}, mainwp://help/tool/{name})
161
+ // MUST be routed through validateResourceUri() for security validation.
162
+ // - Do not introduce new dynamic URI patterns without using validateResourceUri().
163
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
164
+ const { uri } = request.params;
165
+ try {
166
+ // Static URI handlers (no validation needed - exact match)
167
+ if (uri === 'mainwp://abilities') {
168
+ const abilities = await fetchAbilities(config, false, logger);
169
+ return {
170
+ contents: [
171
+ {
172
+ uri,
173
+ mimeType: 'application/json',
174
+ text: formatJson(config, abilities),
175
+ },
176
+ ],
177
+ };
178
+ }
179
+ if (uri === 'mainwp://categories') {
180
+ const categories = await fetchCategories(config, false, logger);
181
+ return {
182
+ contents: [
183
+ {
184
+ uri,
185
+ mimeType: 'application/json',
186
+ text: formatJson(config, categories),
187
+ },
188
+ ],
189
+ };
190
+ }
191
+ if (uri === 'mainwp://status') {
192
+ // Test connection by fetching abilities
193
+ // Redact dashboardUrl to host-only to avoid leaking full URL path to untrusted MCP clients
194
+ let redactedHost;
195
+ try {
196
+ redactedHost = new URL(config.dashboardUrl).host;
197
+ }
198
+ catch {
199
+ redactedHost = '[invalid-url]';
200
+ }
201
+ try {
202
+ const abilities = await fetchAbilities(config, true, logger); // Force refresh
203
+ return {
204
+ contents: [
205
+ {
206
+ uri,
207
+ mimeType: 'application/json',
208
+ text: formatJson(config, {
209
+ connected: true,
210
+ dashboardHost: redactedHost,
211
+ abilitiesCount: abilities.length,
212
+ sessionData: getSessionDataUsage(config),
213
+ }),
214
+ },
215
+ ],
216
+ };
217
+ }
218
+ catch (error) {
219
+ const errorMsg = error instanceof Error ? error.message : String(error);
220
+ return {
221
+ contents: [
222
+ {
223
+ uri,
224
+ mimeType: 'application/json',
225
+ text: formatJson(config, {
226
+ connected: false,
227
+ dashboardHost: redactedHost,
228
+ error: sanitizeError(errorMsg),
229
+ }),
230
+ },
231
+ ],
232
+ };
233
+ }
234
+ }
235
+ // Handle help resource: comprehensive documentation
236
+ if (uri === 'mainwp://help') {
237
+ const abilities = await fetchAbilities(config, false, logger);
238
+ const helpDoc = generateHelpDocument(abilities);
239
+ return {
240
+ contents: [
241
+ {
242
+ uri,
243
+ mimeType: 'application/json',
244
+ text: formatJson(config, helpDoc),
245
+ },
246
+ ],
247
+ };
248
+ }
249
+ // Validate and parse the resource URI (throws on invalid URIs)
250
+ const parsed = validateResourceUri(uri);
251
+ // Handle site resource template: mainwp://site/{id}
252
+ if (parsed.type === 'site' && parsed.params?.site_id) {
253
+ const result = await executeAbility(config, 'mainwp/get-site-v1', { site_id: parsed.params.site_id }, logger);
254
+ return {
255
+ contents: [
256
+ {
257
+ uri,
258
+ mimeType: 'application/json',
259
+ text: formatJson(config, result),
260
+ },
261
+ ],
262
+ };
263
+ }
264
+ // Handle tool help resource template: mainwp://help/tool/{tool_name}
265
+ if (parsed.type === 'tool-help' && parsed.params?.tool_name) {
266
+ const toolName = parsed.params.tool_name;
267
+ // Hardcoded 'mainwp' namespace - this server only supports MainWP abilities
268
+ const abilityName = toolNameToAbilityName(toolName, 'mainwp');
269
+ const ability = await getAbility(config, abilityName, logger);
270
+ if (!ability) {
271
+ throw McpErrorFactory.resourceNotFound(uri);
272
+ }
273
+ return {
274
+ contents: [
275
+ {
276
+ uri,
277
+ mimeType: 'application/json',
278
+ text: formatJson(config, generateToolHelp(ability)),
279
+ },
280
+ ],
281
+ };
282
+ }
283
+ // If we get here, the URI was valid but not handled by the code above
284
+ throw new Error(`Unhandled resource type: ${parsed.type}`);
285
+ }
286
+ catch (error) {
287
+ return {
288
+ contents: [
289
+ {
290
+ uri,
291
+ mimeType: 'application/json',
292
+ text: formatErrorResponse(error, sanitizeError),
293
+ },
294
+ ],
295
+ };
296
+ }
297
+ });
298
+ // Handler: List available prompts
299
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
300
+ return { prompts: getPromptList() };
301
+ });
302
+ // Handler: Get a specific prompt
303
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
304
+ const { name, arguments: args } = request.params;
305
+ try {
306
+ // Validate prompt arguments before processing
307
+ if (args) {
308
+ validateInput(args);
309
+ }
310
+ return getPrompt(name, args);
311
+ }
312
+ catch (error) {
313
+ // Preserve structured MCP errors (e.g., from validateInput)
314
+ if (error instanceof McpError) {
315
+ throw error;
316
+ }
317
+ // Sanitize unexpected errors
318
+ const errorMessage = error instanceof Error ? error.message : String(error);
319
+ throw new Error(sanitizeError(errorMessage), { cause: error });
320
+ }
321
+ });
322
+ // Handler: Argument completions
323
+ server.setRequestHandler(CompleteRequestSchema, async (request) => {
324
+ const { ref, argument } = request.params;
325
+ // Handle prompt argument completions
326
+ if (ref.type === 'ref/prompt') {
327
+ const promptName = ref.name;
328
+ const argName = argument.name;
329
+ // Get static completions for known argument types
330
+ let values = getPromptArgumentCompletions(promptName, argName);
331
+ // For site_id arguments, try to fetch site list dynamically
332
+ if ((argName === 'site_id' || argName === 'site_ids') && values.length === 0) {
333
+ try {
334
+ const abilities = await fetchAbilities(config, false, logger);
335
+ const listSitesAbility = abilities.find(a => a.name === 'mainwp/list-sites-v1');
336
+ if (listSitesAbility) {
337
+ const result = await executeAbility(config, 'mainwp/list-sites-v1', {}, logger);
338
+ if (Array.isArray(result)) {
339
+ // Filter to only valid site IDs
340
+ values = result
341
+ .filter((site) => isValidId(site.id))
342
+ .map((site) => String(site.id));
343
+ }
344
+ }
345
+ }
346
+ catch {
347
+ // Ignore errors, return empty completions
348
+ }
349
+ }
350
+ // Filter by current input value if provided
351
+ const currentValue = argument.value || '';
352
+ const filteredValues = values.filter(v => v.toLowerCase().startsWith(currentValue.toLowerCase()));
353
+ return {
354
+ completion: {
355
+ values: filteredValues.slice(0, MAX_COMPLETION_SUGGESTIONS),
356
+ hasMore: filteredValues.length > MAX_COMPLETION_SUGGESTIONS,
357
+ total: filteredValues.length,
358
+ },
359
+ };
360
+ }
361
+ // Default: no completions
362
+ return {
363
+ completion: {
364
+ values: [],
365
+ hasMore: false,
366
+ total: 0,
367
+ },
368
+ };
369
+ });
370
+ // Handler: List resource templates
371
+ server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
372
+ return {
373
+ resourceTemplates: [
374
+ {
375
+ uriTemplate: 'mainwp://site/{site_id}',
376
+ name: 'Site Details',
377
+ description: 'Get detailed information about a specific site by ID',
378
+ mimeType: 'application/json',
379
+ },
380
+ {
381
+ uriTemplate: 'mainwp://help/tool/{tool_name}',
382
+ name: 'Tool Documentation',
383
+ description: 'Get detailed documentation for a specific tool including parameters and safety features',
384
+ mimeType: 'application/json',
385
+ },
386
+ ],
387
+ };
388
+ });
389
+ // Register cache refresh callback for list_changed notifications
390
+ onCacheRefresh(() => {
391
+ server.sendToolListChanged().catch(() => {
392
+ // Ignore if not connected
393
+ });
394
+ });
395
+ return { server, logger };
396
+ }
397
+ /**
398
+ * Validate credentials by attempting to fetch abilities from the MainWP Dashboard.
399
+ * Provides enhanced error messages for common failure scenarios.
400
+ *
401
+ * @param config - Server configuration
402
+ * @param logger - Logger for status messages
403
+ * @returns The fetched abilities array on success
404
+ * @throws Error with actionable message on failure
405
+ */
406
+ async function validateCredentials(config, logger) {
407
+ try {
408
+ const abilities = await fetchAbilities(config, false, logger);
409
+ logger.info('Credential validation successful: Connected to MainWP Dashboard');
410
+ return abilities;
411
+ }
412
+ catch (error) {
413
+ const message = error instanceof Error ? error.message : String(error);
414
+ const lowerMessage = message.toLowerCase();
415
+ // Authentication failures (401/403) - provide auth-type specific guidance
416
+ if (lowerMessage.includes('401') ||
417
+ lowerMessage.includes('403') ||
418
+ lowerMessage.includes('unauthorized') ||
419
+ lowerMessage.includes('forbidden')) {
420
+ const authHint = config.authType === 'basic'
421
+ ? 'Verify MAINWP_USER and MAINWP_APP_PASSWORD (or username/appPassword in settings.json) are correct and the user has REST API access.'
422
+ : 'Verify MAINWP_TOKEN (or apiToken in settings.json) is correct and has not expired.';
423
+ throw new Error(`Authentication failed: Invalid credentials. ${authHint}`, {
424
+ cause: error,
425
+ });
426
+ }
427
+ // Endpoint not found (404) - likely missing Abilities API plugin
428
+ if (lowerMessage.includes('404') || lowerMessage.includes('not found')) {
429
+ throw new Error('Abilities API endpoint not found. Verify MAINWP_URL points to a MainWP Dashboard with the Abilities API plugin installed.', { cause: error });
430
+ }
431
+ // Connection timeout
432
+ if (lowerMessage.includes('timeout')) {
433
+ throw new Error('Connection timeout. Verify MAINWP_URL is reachable and the server is responding.', { cause: error });
434
+ }
435
+ // SSL/TLS certificate errors
436
+ if (lowerMessage.includes('certificate') ||
437
+ lowerMessage.includes('ssl') ||
438
+ lowerMessage.includes('tls') ||
439
+ lowerMessage.includes('self-signed') ||
440
+ lowerMessage.includes('unable to verify')) {
441
+ throw new Error('SSL certificate verification failed. For self-signed certificates, set MAINWP_SKIP_SSL_VERIFY=true (development only).', { cause: error });
442
+ }
443
+ // Network connectivity errors
444
+ if (lowerMessage.includes('enotfound') ||
445
+ lowerMessage.includes('econnrefused') ||
446
+ lowerMessage.includes('network') ||
447
+ lowerMessage.includes('getaddrinfo') ||
448
+ lowerMessage.includes('econnreset')) {
449
+ throw new Error('Network error: Cannot reach MAINWP_URL. Verify the URL is correct and the server is accessible.', { cause: error });
450
+ }
451
+ // Other errors - re-throw with prefix
452
+ throw new Error(`Credential validation failed: ${message}`, { cause: error });
453
+ }
454
+ }
455
+ /**
456
+ * Main entry point
457
+ */
458
+ async function main() {
459
+ // Use stderr logger before server is initialized
460
+ const startupLogger = createStderrLogger();
461
+ try {
462
+ // Load configuration from environment
463
+ const config = loadConfig();
464
+ // Initialize rate limiter
465
+ initRateLimiter(config.rateLimit);
466
+ startupLogger.info(`MainWP MCP Server v${SERVER_VERSION}`);
467
+ startupLogger.info(`Dashboard: ${config.dashboardUrl}`);
468
+ startupLogger.info(`Auth: ${config.authType === 'basic' ? 'Basic Auth' : 'Bearer Token'}`);
469
+ startupLogger.info(`Config source: ${config.configSource}`);
470
+ startupLogger.info(`Session data limit: ${(config.maxSessionData / 1048576).toFixed(1)}MB`);
471
+ if (config.skipSslVerify) {
472
+ startupLogger.error('╔══════════════════════════════════════════════════════════════╗');
473
+ startupLogger.error('║ WARNING: SSL verification disabled ║');
474
+ startupLogger.error('║ Connection is vulnerable to man-in-the-middle attacks ║');
475
+ startupLogger.error('║ Only use for local development with self-signed certs ║');
476
+ startupLogger.error('╚══════════════════════════════════════════════════════════════╝');
477
+ }
478
+ // Validate credentials with fail-fast behavior
479
+ startupLogger.info('Validating credentials...');
480
+ const abilities = await validateCredentials(config, startupLogger);
481
+ startupLogger.info(`Connected! Found ${abilities.length} abilities`);
482
+ abilities.forEach(a => startupLogger.debug(` - ${a.name}: ${a.label}`));
483
+ // Create server (returns server + structured logger)
484
+ const { server, logger } = await createServer(config);
485
+ // Connect via stdio transport
486
+ const transport = new StdioServerTransport();
487
+ await server.connect(transport);
488
+ logger.info('MCP server running on stdio');
489
+ // Handle graceful shutdown for both SIGINT and SIGTERM
490
+ const shutdown = async (signal) => {
491
+ logger.info(`Received ${signal}, shutting down...`);
492
+ clearCache();
493
+ await server.close();
494
+ process.exit(0);
495
+ };
496
+ process.on('SIGINT', () => shutdown('SIGINT'));
497
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
498
+ }
499
+ catch (error) {
500
+ startupLogger.error(`Fatal error: ${error instanceof Error ? error.message : error}`);
501
+ process.exit(1);
502
+ }
503
+ }
504
+ // Run the server
505
+ main();
506
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Structured Logging Utility
3
+ *
4
+ * Provides MCP-compliant logging with severity levels.
5
+ * Uses server.sendLoggingMessage() when connected, falls back to stderr.
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ export type LogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error' | 'critical' | 'alert' | 'emergency';
9
+ export interface Logger {
10
+ debug(message: string, data?: Record<string, unknown>): void;
11
+ info(message: string, data?: Record<string, unknown>): void;
12
+ notice(message: string, data?: Record<string, unknown>): void;
13
+ warning(message: string, data?: Record<string, unknown>): void;
14
+ error(message: string, data?: Record<string, unknown>): void;
15
+ critical(message: string, data?: Record<string, unknown>): void;
16
+ }
17
+ /**
18
+ * Create a logger that sends structured messages to MCP clients.
19
+ *
20
+ * @param server - The MCP server instance (requires logging capability)
21
+ * @param loggerName - Name to identify the logging source (default: 'mainwp-mcp')
22
+ */
23
+ export declare function createLogger(server: Server, loggerName?: string): Logger;
24
+ /**
25
+ * Create a child logger that automatically includes a request correlation ID
26
+ * in every log entry. Useful for tracing a tool call across log entries.
27
+ */
28
+ export declare function withRequestId(logger: Logger, requestId: string): Logger;
29
+ /**
30
+ * Simple stderr logger for use before MCP server is initialized.
31
+ * Does not require a server instance.
32
+ */
33
+ export declare function createStderrLogger(loggerName?: string): Logger;
34
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,WAAW,CAAC;AAEhB,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACjE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,SAAe,GAAG,MAAM,CA8B9E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAavE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,SAAe,GAAG,MAAM,CAepE"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Structured Logging Utility
3
+ *
4
+ * Provides MCP-compliant logging with severity levels.
5
+ * Uses server.sendLoggingMessage() when connected, falls back to stderr.
6
+ */
7
+ /**
8
+ * Create a logger that sends structured messages to MCP clients.
9
+ *
10
+ * @param server - The MCP server instance (requires logging capability)
11
+ * @param loggerName - Name to identify the logging source (default: 'mainwp-mcp')
12
+ */
13
+ export function createLogger(server, loggerName = 'mainwp-mcp') {
14
+ const log = (level, message, data) => {
15
+ // Build the log data payload
16
+ const logData = data ? { message, ...data } : message;
17
+ // Try to send via MCP protocol
18
+ server
19
+ .sendLoggingMessage({
20
+ level,
21
+ logger: loggerName,
22
+ data: logData,
23
+ })
24
+ .catch(() => {
25
+ // Fall back to stderr if server not connected or logging not enabled
26
+ const timestamp = new Date().toISOString();
27
+ const dataStr = data ? ` ${JSON.stringify(data)}` : '';
28
+ console.error(`[${timestamp}] [${level.toUpperCase()}] [${loggerName}] ${message}${dataStr}`);
29
+ });
30
+ };
31
+ return {
32
+ debug: (message, data) => log('debug', message, data),
33
+ info: (message, data) => log('info', message, data),
34
+ notice: (message, data) => log('notice', message, data),
35
+ warning: (message, data) => log('warning', message, data),
36
+ error: (message, data) => log('error', message, data),
37
+ critical: (message, data) => log('critical', message, data),
38
+ };
39
+ }
40
+ /**
41
+ * Create a child logger that automatically includes a request correlation ID
42
+ * in every log entry. Useful for tracing a tool call across log entries.
43
+ */
44
+ export function withRequestId(logger, requestId) {
45
+ const wrap = (fn) => (message, data) => fn(message, { ...data, requestId });
46
+ return {
47
+ debug: wrap(logger.debug.bind(logger)),
48
+ info: wrap(logger.info.bind(logger)),
49
+ notice: wrap(logger.notice.bind(logger)),
50
+ warning: wrap(logger.warning.bind(logger)),
51
+ error: wrap(logger.error.bind(logger)),
52
+ critical: wrap(logger.critical.bind(logger)),
53
+ };
54
+ }
55
+ /**
56
+ * Simple stderr logger for use before MCP server is initialized.
57
+ * Does not require a server instance.
58
+ */
59
+ export function createStderrLogger(loggerName = 'mainwp-mcp') {
60
+ const log = (level, message, data) => {
61
+ const timestamp = new Date().toISOString();
62
+ const dataStr = data ? ` ${JSON.stringify(data)}` : '';
63
+ console.error(`[${timestamp}] [${level.toUpperCase()}] [${loggerName}] ${message}${dataStr}`);
64
+ };
65
+ return {
66
+ debug: (message, data) => log('debug', message, data),
67
+ info: (message, data) => log('info', message, data),
68
+ notice: (message, data) => log('notice', message, data),
69
+ warning: (message, data) => log('warning', message, data),
70
+ error: (message, data) => log('error', message, data),
71
+ critical: (message, data) => log('critical', message, data),
72
+ };
73
+ }
74
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}