mcp-wordpress 1.2.2 → 1.3.0

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 (251) hide show
  1. package/README.md +210 -182
  2. package/dist/cache/CacheInvalidation.d.ts +3 -3
  3. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  4. package/dist/cache/CacheInvalidation.js +119 -119
  5. package/dist/cache/CacheInvalidation.js.map +1 -1
  6. package/dist/cache/CacheManager.d.ts +5 -0
  7. package/dist/cache/CacheManager.d.ts.map +1 -1
  8. package/dist/cache/CacheManager.js +26 -16
  9. package/dist/cache/CacheManager.js.map +1 -1
  10. package/dist/cache/HttpCacheWrapper.d.ts +1 -1
  11. package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
  12. package/dist/cache/HttpCacheWrapper.js +29 -29
  13. package/dist/cache/HttpCacheWrapper.js.map +1 -1
  14. package/dist/cache/__tests__/CacheInvalidation.test.js +96 -94
  15. package/dist/cache/__tests__/CacheInvalidation.test.js.map +1 -1
  16. package/dist/cache/__tests__/CacheManager.test.js +113 -113
  17. package/dist/cache/__tests__/CacheManager.test.js.map +1 -1
  18. package/dist/cache/__tests__/CachedWordPressClient.test.js +102 -99
  19. package/dist/cache/__tests__/CachedWordPressClient.test.js.map +1 -1
  20. package/dist/cache/__tests__/HttpCacheWrapper.test.js +98 -95
  21. package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
  22. package/dist/cache/index.d.ts +7 -7
  23. package/dist/cache/index.d.ts.map +1 -1
  24. package/dist/cache/index.js +4 -4
  25. package/dist/cache/index.js.map +1 -1
  26. package/dist/client/CachedWordPressClient.d.ts +4 -4
  27. package/dist/client/CachedWordPressClient.d.ts.map +1 -1
  28. package/dist/client/CachedWordPressClient.js +55 -51
  29. package/dist/client/CachedWordPressClient.js.map +1 -1
  30. package/dist/client/api.d.ts +10 -10
  31. package/dist/client/api.js +158 -158
  32. package/dist/client/api.js.map +1 -1
  33. package/dist/client/auth.d.ts +2 -2
  34. package/dist/client/auth.js +72 -72
  35. package/dist/client/managers/AuthenticationManager.d.ts +2 -2
  36. package/dist/client/managers/AuthenticationManager.js +46 -46
  37. package/dist/client/managers/BaseManager.d.ts +1 -1
  38. package/dist/client/managers/BaseManager.js +9 -9
  39. package/dist/client/managers/RequestManager.d.ts +5 -3
  40. package/dist/client/managers/RequestManager.d.ts.map +1 -1
  41. package/dist/client/managers/RequestManager.js +39 -19
  42. package/dist/client/managers/RequestManager.js.map +1 -1
  43. package/dist/client/managers/index.d.ts +3 -3
  44. package/dist/client/managers/index.js +3 -3
  45. package/dist/config/ConfigurationSchema.d.ts +2 -2
  46. package/dist/config/ConfigurationSchema.d.ts.map +1 -1
  47. package/dist/config/ConfigurationSchema.js +40 -40
  48. package/dist/config/ConfigurationSchema.js.map +1 -1
  49. package/dist/config/ServerConfiguration.d.ts +2 -2
  50. package/dist/config/ServerConfiguration.js +35 -35
  51. package/dist/config/ServerConfiguration.js.map +1 -1
  52. package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
  53. package/dist/docs/DocumentationGenerator.js +296 -255
  54. package/dist/docs/DocumentationGenerator.js.map +1 -1
  55. package/dist/docs/MarkdownFormatter.d.ts +1 -1
  56. package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
  57. package/dist/docs/MarkdownFormatter.js +60 -51
  58. package/dist/docs/MarkdownFormatter.js.map +1 -1
  59. package/dist/docs/index.d.ts +3 -3
  60. package/dist/docs/index.d.ts.map +1 -1
  61. package/dist/docs/index.js +2 -2
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +16 -16
  64. package/dist/index.js.map +1 -1
  65. package/dist/mcp-wordpress-1.3.0.tgz +0 -0
  66. package/dist/performance/MetricsCollector.d.ts +3 -3
  67. package/dist/performance/MetricsCollector.d.ts.map +1 -1
  68. package/dist/performance/MetricsCollector.js +33 -27
  69. package/dist/performance/MetricsCollector.js.map +1 -1
  70. package/dist/performance/PerformanceAnalytics.d.ts +12 -12
  71. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
  72. package/dist/performance/PerformanceAnalytics.js +200 -154
  73. package/dist/performance/PerformanceAnalytics.js.map +1 -1
  74. package/dist/performance/PerformanceMonitor.d.ts +5 -5
  75. package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
  76. package/dist/performance/PerformanceMonitor.js +53 -52
  77. package/dist/performance/PerformanceMonitor.js.map +1 -1
  78. package/dist/performance/index.d.ts +6 -6
  79. package/dist/performance/index.d.ts.map +1 -1
  80. package/dist/performance/index.js +3 -3
  81. package/dist/security/InputValidator.d.ts +1 -1
  82. package/dist/security/InputValidator.d.ts.map +1 -1
  83. package/dist/security/InputValidator.js +111 -88
  84. package/dist/security/InputValidator.js.map +1 -1
  85. package/dist/security/SecurityConfig.d.ts +5 -5
  86. package/dist/security/SecurityConfig.js +92 -92
  87. package/dist/security/SecurityConfig.js.map +1 -1
  88. package/dist/server/ConnectionTester.d.ts +1 -1
  89. package/dist/server/ConnectionTester.d.ts.map +1 -1
  90. package/dist/server/ConnectionTester.js +4 -4
  91. package/dist/server/ConnectionTester.js.map +1 -1
  92. package/dist/server/ToolRegistry.d.ts +2 -2
  93. package/dist/server/ToolRegistry.d.ts.map +1 -1
  94. package/dist/server/ToolRegistry.js +35 -32
  95. package/dist/server/ToolRegistry.js.map +1 -1
  96. package/dist/server.d.ts +2 -2
  97. package/dist/server.js +2 -2
  98. package/dist/tools/BaseToolManager.js +5 -5
  99. package/dist/tools/auth.d.ts +2 -2
  100. package/dist/tools/auth.d.ts.map +1 -1
  101. package/dist/tools/auth.js +32 -31
  102. package/dist/tools/auth.js.map +1 -1
  103. package/dist/tools/cache.d.ts +1 -1
  104. package/dist/tools/cache.d.ts.map +1 -1
  105. package/dist/tools/cache.js +71 -71
  106. package/dist/tools/cache.js.map +1 -1
  107. package/dist/tools/comments.d.ts +2 -2
  108. package/dist/tools/comments.d.ts.map +1 -1
  109. package/dist/tools/comments.js +79 -79
  110. package/dist/tools/comments.js.map +1 -1
  111. package/dist/tools/index.d.ts +10 -10
  112. package/dist/tools/index.js +10 -10
  113. package/dist/tools/media.d.ts +2 -2
  114. package/dist/tools/media.js +80 -80
  115. package/dist/tools/pages.d.ts +2 -2
  116. package/dist/tools/pages.d.ts.map +1 -1
  117. package/dist/tools/pages.js +75 -75
  118. package/dist/tools/pages.js.map +1 -1
  119. package/dist/tools/performance.d.ts +1 -1
  120. package/dist/tools/performance.d.ts.map +1 -1
  121. package/dist/tools/performance.js +311 -287
  122. package/dist/tools/performance.js.map +1 -1
  123. package/dist/tools/posts.d.ts +2 -2
  124. package/dist/tools/posts.d.ts.map +1 -1
  125. package/dist/tools/posts.js +94 -94
  126. package/dist/tools/posts.js.map +1 -1
  127. package/dist/tools/site.d.ts +2 -2
  128. package/dist/tools/site.d.ts.map +1 -1
  129. package/dist/tools/site.js +60 -60
  130. package/dist/tools/site.js.map +1 -1
  131. package/dist/tools/taxonomies.d.ts +2 -2
  132. package/dist/tools/taxonomies.js +89 -89
  133. package/dist/tools/users.d.ts +2 -2
  134. package/dist/tools/users.js +68 -68
  135. package/dist/tools/users.js.map +1 -1
  136. package/dist/types/client.d.ts +13 -13
  137. package/dist/types/client.d.ts.map +1 -1
  138. package/dist/types/client.js +12 -12
  139. package/dist/types/client.js.map +1 -1
  140. package/dist/types/index.d.ts +19 -19
  141. package/dist/types/index.d.ts.map +1 -1
  142. package/dist/types/index.js +3 -3
  143. package/dist/types/mcp.d.ts +7 -7
  144. package/dist/types/wordpress.d.ts +21 -21
  145. package/dist/types/wordpress.d.ts.map +1 -1
  146. package/dist/utils/debug.d.ts +2 -2
  147. package/dist/utils/debug.js +28 -28
  148. package/dist/utils/error.d.ts.map +1 -1
  149. package/dist/utils/error.js +13 -13
  150. package/dist/utils/error.js.map +1 -1
  151. package/dist/utils/toolWrapper.d.ts.map +1 -1
  152. package/dist/utils/toolWrapper.js +5 -5
  153. package/dist/utils/toolWrapper.js.map +1 -1
  154. package/dist/utils/validation.d.ts.map +1 -1
  155. package/dist/utils/validation.js +41 -31
  156. package/dist/utils/validation.js.map +1 -1
  157. package/docs/CACHING.md +36 -2
  158. package/docs/DOCKER.md +24 -18
  159. package/docs/PERFORMANCE_MONITORING.md +49 -1
  160. package/docs/SECURITY_TESTING.md +30 -1
  161. package/docs/api/README.md +9 -1
  162. package/docs/api/summary.json +1 -1
  163. package/docs/contract-testing.md +24 -3
  164. package/docs/developer/GITHUB_ACTIONS_SETUP.md +8 -2
  165. package/docs/developer/MAINTENANCE.md +29 -3
  166. package/docs/developer/MIGRATION_GUIDE.md +13 -1
  167. package/docs/developer/NPM_AUTH_SETUP.md +13 -2
  168. package/docs/developer/REFACTORING.md +31 -1
  169. package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +18 -7
  170. package/docs/releases/RELEASE_NOTES_v1.1.2.md +31 -5
  171. package/docs/user-guides/DOCKER_SETUP.md +264 -0
  172. package/docs/user-guides/DTX_SETUP.md +327 -0
  173. package/docs/user-guides/NPM_SETUP.md +109 -0
  174. package/docs/user-guides/NPX_SETUP.md +281 -0
  175. package/docs/wordpress-rest-api-authentication-troubleshooting.md +13 -2
  176. package/package.json +27 -8
  177. package/src/cache/CacheInvalidation.ts +140 -132
  178. package/src/cache/CacheManager.ts +40 -29
  179. package/src/cache/HttpCacheWrapper.ts +105 -68
  180. package/src/cache/__tests__/CacheInvalidation.test.ts +123 -118
  181. package/src/cache/__tests__/CacheManager.test.ts +156 -152
  182. package/src/cache/__tests__/CachedWordPressClient.test.ts +131 -116
  183. package/src/cache/__tests__/HttpCacheWrapper.test.ts +118 -115
  184. package/src/cache/index.ts +13 -13
  185. package/src/client/CachedWordPressClient.ts +90 -80
  186. package/src/client/api.ts +205 -205
  187. package/src/client/auth.ts +80 -80
  188. package/src/client/managers/AuthenticationManager.ts +61 -61
  189. package/src/client/managers/BaseManager.ts +11 -11
  190. package/src/client/managers/RequestManager.ts +79 -47
  191. package/src/client/managers/index.ts +3 -3
  192. package/src/config/ConfigurationSchema.ts +44 -44
  193. package/src/config/ServerConfiguration.ts +39 -39
  194. package/src/docs/DocumentationGenerator.ts +402 -295
  195. package/src/docs/MarkdownFormatter.ts +94 -69
  196. package/src/docs/index.ts +4 -4
  197. package/src/index.ts +24 -21
  198. package/src/performance/MetricsCollector.ts +90 -58
  199. package/src/performance/PerformanceAnalytics.ts +386 -262
  200. package/src/performance/PerformanceMonitor.ts +152 -118
  201. package/src/performance/index.ts +9 -9
  202. package/src/security/InputValidator.ts +148 -91
  203. package/src/security/SecurityConfig.ts +94 -94
  204. package/src/server/ConnectionTester.ts +21 -15
  205. package/src/server/ToolRegistry.ts +64 -51
  206. package/src/server.ts +2 -2
  207. package/src/tools/BaseToolManager.ts +6 -6
  208. package/src/tools/auth.ts +42 -37
  209. package/src/tools/cache.ts +85 -81
  210. package/src/tools/comments.ts +93 -91
  211. package/src/tools/index.ts +10 -10
  212. package/src/tools/media.ts +89 -89
  213. package/src/tools/pages.ts +89 -87
  214. package/src/tools/performance.ts +443 -352
  215. package/src/tools/posts.ts +109 -107
  216. package/src/tools/site.ts +86 -77
  217. package/src/tools/taxonomies.ts +102 -102
  218. package/src/tools/users.ts +77 -77
  219. package/src/types/client.ts +157 -60
  220. package/src/types/index.ts +49 -27
  221. package/src/types/mcp.ts +15 -15
  222. package/src/types/wordpress.ts +57 -29
  223. package/src/utils/debug.ts +37 -37
  224. package/src/utils/error.ts +47 -25
  225. package/src/utils/toolWrapper.ts +12 -8
  226. package/src/utils/validation.ts +116 -65
  227. package/dist/client/WordPressClient.d.ts +0 -81
  228. package/dist/client/WordPressClient.d.ts.map +0 -1
  229. package/dist/client/WordPressClient.js +0 -354
  230. package/dist/client/WordPressClient.js.map +0 -1
  231. package/dist/performance/AnomalyDetector.d.ts +0 -63
  232. package/dist/performance/AnomalyDetector.d.ts.map +0 -1
  233. package/dist/performance/AnomalyDetector.js +0 -222
  234. package/dist/performance/AnomalyDetector.js.map +0 -1
  235. package/dist/performance/BenchmarkAnalyzer.d.ts +0 -67
  236. package/dist/performance/BenchmarkAnalyzer.d.ts.map +0 -1
  237. package/dist/performance/BenchmarkAnalyzer.js +0 -301
  238. package/dist/performance/BenchmarkAnalyzer.js.map +0 -1
  239. package/dist/performance/TrendAnalyzer.d.ts +0 -69
  240. package/dist/performance/TrendAnalyzer.d.ts.map +0 -1
  241. package/dist/performance/TrendAnalyzer.js +0 -203
  242. package/dist/performance/TrendAnalyzer.js.map +0 -1
  243. package/dist/tools/BaseToolClass.d.ts +0 -76
  244. package/dist/tools/BaseToolClass.d.ts.map +0 -1
  245. package/dist/tools/BaseToolClass.js +0 -104
  246. package/dist/tools/BaseToolClass.js.map +0 -1
  247. package/dist/tools/base.d.ts +0 -37
  248. package/dist/tools/base.d.ts.map +0 -1
  249. package/dist/tools/base.js +0 -60
  250. package/dist/tools/base.js.map +0 -1
  251. package/docs/user-guides/CLAUDE_DESKTOP_SETUP.md +0 -187
@@ -2,68 +2,68 @@
2
2
  * Security configuration and constants for MCP WordPress
3
3
  */
4
4
 
5
- import { randomBytes } from 'crypto';
5
+ import { randomBytes } from "crypto";
6
6
 
7
7
  export const SecurityConfig = {
8
8
  // Rate limiting
9
9
  rateLimiting: {
10
10
  default: {
11
11
  windowMs: 60 * 1000, // 1 minute
12
- maxRequests: 60
12
+ maxRequests: 60,
13
13
  },
14
14
  authentication: {
15
15
  windowMs: 5 * 60 * 1000, // 5 minutes
16
- maxAttempts: 5
16
+ maxAttempts: 5,
17
17
  },
18
18
  upload: {
19
19
  windowMs: 60 * 1000, // 1 minute
20
- maxRequests: 10
21
- }
20
+ maxRequests: 10,
21
+ },
22
22
  },
23
23
 
24
24
  // File upload restrictions
25
25
  fileUpload: {
26
26
  maxSizeMB: 10,
27
27
  allowedMimeTypes: [
28
- 'image/jpeg',
29
- 'image/png',
30
- 'image/gif',
31
- 'image/webp',
32
- 'image/svg+xml',
33
- 'application/pdf',
34
- 'application/msword',
35
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
36
- 'application/vnd.ms-excel',
37
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
38
- 'text/plain',
39
- 'text/csv'
28
+ "image/jpeg",
29
+ "image/png",
30
+ "image/gif",
31
+ "image/webp",
32
+ "image/svg+xml",
33
+ "application/pdf",
34
+ "application/msword",
35
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
36
+ "application/vnd.ms-excel",
37
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
38
+ "text/plain",
39
+ "text/csv",
40
40
  ],
41
41
  // Dangerous file extensions to block
42
42
  blockedExtensions: [
43
- '.exe',
44
- '.bat',
45
- '.cmd',
46
- '.com',
47
- '.pif',
48
- '.scr',
49
- '.vbs',
50
- '.js',
51
- '.jar',
52
- '.zip',
53
- '.rar',
54
- '.tar',
55
- '.php',
56
- '.php3',
57
- '.php4',
58
- '.php5',
59
- '.phtml',
60
- '.sh',
61
- '.bash',
62
- '.zsh',
63
- '.fish',
64
- '.ps1',
65
- '.psm1'
66
- ]
43
+ ".exe",
44
+ ".bat",
45
+ ".cmd",
46
+ ".com",
47
+ ".pif",
48
+ ".scr",
49
+ ".vbs",
50
+ ".js",
51
+ ".jar",
52
+ ".zip",
53
+ ".rar",
54
+ ".tar",
55
+ ".php",
56
+ ".php3",
57
+ ".php4",
58
+ ".php5",
59
+ ".phtml",
60
+ ".sh",
61
+ ".bash",
62
+ ".zsh",
63
+ ".fish",
64
+ ".ps1",
65
+ ".psm1",
66
+ ],
67
67
  },
68
68
 
69
69
  // Input validation
@@ -76,58 +76,58 @@ export const SecurityConfig = {
76
76
  maxUsernameLength: 60,
77
77
  minUsernameLength: 3,
78
78
  maxPasswordLength: 128,
79
- minPasswordLength: 8
79
+ minPasswordLength: 8,
80
80
  },
81
81
 
82
82
  // Request timeouts (milliseconds)
83
83
  timeouts: {
84
84
  default: 30000, // 30 seconds
85
85
  upload: 600000, // 10 minutes
86
- auth: 10000 // 10 seconds
86
+ auth: 10000, // 10 seconds
87
87
  },
88
88
 
89
89
  // Security headers
90
90
  headers: {
91
- 'X-Content-Type-Options': 'nosniff',
92
- 'X-Frame-Options': 'DENY',
93
- 'X-XSS-Protection': '1; mode=block',
94
- 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
95
- 'Content-Security-Policy': 'default-src \'self\''
91
+ "X-Content-Type-Options": "nosniff",
92
+ "X-Frame-Options": "DENY",
93
+ "X-XSS-Protection": "1; mode=block",
94
+ "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
95
+ "Content-Security-Policy": "default-src 'self'",
96
96
  },
97
97
 
98
98
  // Error messages (generic to avoid information disclosure)
99
99
  errorMessages: {
100
- authentication: 'Authentication failed. Please check your credentials.',
101
- authorization: 'You do not have permission to perform this action.',
102
- validation: 'Invalid input provided.',
103
- rateLimit: 'Too many requests. Please try again later.',
104
- serverError: 'An error occurred processing your request.',
105
- notFound: 'The requested resource was not found.'
100
+ authentication: "Authentication failed. Please check your credentials.",
101
+ authorization: "You do not have permission to perform this action.",
102
+ validation: "Invalid input provided.",
103
+ rateLimit: "Too many requests. Please try again later.",
104
+ serverError: "An error occurred processing your request.",
105
+ notFound: "The requested resource was not found.",
106
106
  },
107
107
 
108
108
  // Logging configuration
109
109
  logging: {
110
110
  // Fields to exclude from logs
111
111
  excludeFields: [
112
- 'password',
113
- 'appPassword',
114
- 'app_password',
115
- 'token',
116
- 'secret',
117
- 'authorization',
118
- 'cookie',
119
- 'session',
120
- 'key',
121
- 'apiKey',
122
- 'api_key'
112
+ "password",
113
+ "appPassword",
114
+ "app_password",
115
+ "token",
116
+ "secret",
117
+ "authorization",
118
+ "cookie",
119
+ "session",
120
+ "key",
121
+ "apiKey",
122
+ "api_key",
123
123
  ],
124
124
  // Patterns to redact in log messages
125
125
  redactPatterns: [
126
126
  /password["\s:=]+["']?([^"'\s]+)["']?/gi,
127
127
  /token["\s:=]+["']?([^"'\s]+)["']?/gi,
128
128
  /secret["\s:=]+["']?([^"'\s]+)["']?/gi,
129
- /key["\s:=]+["']?([^"'\s]+)["']?/gi
130
- ]
129
+ /key["\s:=]+["']?([^"'\s]+)["']?/gi,
130
+ ],
131
131
  },
132
132
 
133
133
  // Cache configuration
@@ -145,16 +145,16 @@ export const SecurityConfig = {
145
145
  semiStatic: 2 * 60 * 60 * 1000, // 2 hours - categories, tags, user profiles
146
146
  dynamic: 15 * 60 * 1000, // 15 minutes - posts, pages, comments
147
147
  session: 30 * 60 * 1000, // 30 minutes - authentication, current user
148
- realtime: 60 * 1000 // 1 minute - real-time data
148
+ realtime: 60 * 1000, // 1 minute - real-time data
149
149
  },
150
150
 
151
151
  // Cache-Control headers by data type
152
152
  cacheHeaders: {
153
- static: 'public, max-age=14400', // 4 hours
154
- semiStatic: 'public, max-age=7200', // 2 hours
155
- dynamic: 'public, max-age=900', // 15 minutes
156
- session: 'private, max-age=1800', // 30 minutes
157
- realtime: 'public, max-age=60' // 1 minute
153
+ static: "public, max-age=14400", // 4 hours
154
+ semiStatic: "public, max-age=7200", // 2 hours
155
+ dynamic: "public, max-age=900", // 15 minutes
156
+ session: "private, max-age=1800", // 30 minutes
157
+ realtime: "public, max-age=60", // 1 minute
158
158
  },
159
159
 
160
160
  // Invalidation settings
@@ -162,16 +162,16 @@ export const SecurityConfig = {
162
162
  enabled: true,
163
163
  batchSize: 100, // Max events to process in one batch
164
164
  queueTimeout: 5000, // Max time to wait before processing queue (ms)
165
- enableCascading: true // Allow cascading invalidations
165
+ enableCascading: true, // Allow cascading invalidations
166
166
  },
167
167
 
168
168
  // Memory management
169
169
  cleanup: {
170
170
  interval: 60 * 1000, // Cleanup interval in milliseconds (1 minute)
171
171
  maxMemoryMB: 50, // Maximum memory usage for cache
172
- evictionThreshold: 0.8 // Start evicting when 80% full
173
- }
174
- }
172
+ evictionThreshold: 0.8, // Start evicting when 80% full
173
+ },
174
+ },
175
175
  };
176
176
 
177
177
  /**
@@ -182,7 +182,7 @@ export class SecurityUtils {
182
182
  * Redact sensitive information from objects
183
183
  */
184
184
  static redactSensitiveData(obj: any): any {
185
- if (typeof obj !== 'object' || obj === null) {
185
+ if (typeof obj !== "object" || obj === null) {
186
186
  return obj;
187
187
  }
188
188
 
@@ -191,11 +191,11 @@ export class SecurityUtils {
191
191
  for (const key in redacted) {
192
192
  if (
193
193
  SecurityConfig.logging.excludeFields.some((field) =>
194
- key.toLowerCase().includes(field.toLowerCase())
194
+ key.toLowerCase().includes(field.toLowerCase()),
195
195
  )
196
196
  ) {
197
- redacted[key] = '[REDACTED]';
198
- } else if (typeof redacted[key] === 'object') {
197
+ redacted[key] = "[REDACTED]";
198
+ } else if (typeof redacted[key] === "object") {
199
199
  redacted[key] = SecurityUtils.redactSensitiveData(redacted[key]);
200
200
  }
201
201
  }
@@ -210,7 +210,7 @@ export class SecurityUtils {
210
210
  let redacted = str;
211
211
  for (const pattern of SecurityConfig.logging.redactPatterns) {
212
212
  redacted = redacted.replace(pattern, (match, value) => {
213
- return match.replace(value, '[REDACTED]');
213
+ return match.replace(value, "[REDACTED]");
214
214
  });
215
215
  }
216
216
  return redacted;
@@ -221,10 +221,10 @@ export class SecurityUtils {
221
221
  */
222
222
  static generateSecureToken(length: number = 32): string {
223
223
  const chars =
224
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
224
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
225
225
  const array = new Uint8Array(length);
226
226
 
227
- if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
227
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
228
228
  crypto.getRandomValues(array);
229
229
  } else {
230
230
  // Fallback for Node.js
@@ -232,7 +232,7 @@ export class SecurityUtils {
232
232
  array.set(buffer);
233
233
  }
234
234
 
235
- return Array.from(array, (byte) => chars[byte % chars.length]).join('');
235
+ return Array.from(array, (byte) => chars[byte % chars.length]).join("");
236
236
  }
237
237
 
238
238
  /**
@@ -247,10 +247,10 @@ export class SecurityUtils {
247
247
  * Sanitize log output
248
248
  */
249
249
  static sanitizeForLog(data: any): any {
250
- if (typeof data === 'string') {
250
+ if (typeof data === "string") {
251
251
  return SecurityUtils.redactString(data);
252
252
  }
253
- if (typeof data === 'object') {
253
+ if (typeof data === "object") {
254
254
  return SecurityUtils.redactSensitiveData(data);
255
255
  }
256
256
  return data;
@@ -262,18 +262,18 @@ export class SecurityUtils {
262
262
  */
263
263
  export function createSecureError(
264
264
  error: any,
265
- fallbackMessage: string = SecurityConfig.errorMessages.serverError
265
+ fallbackMessage: string = SecurityConfig.errorMessages.serverError,
266
266
  ): Error {
267
267
  // Log the actual error for debugging (with sanitization)
268
- if (process.env.NODE_ENV !== 'production') {
269
- console.error('Secure Error:', SecurityUtils.sanitizeForLog(error));
268
+ if (process.env.NODE_ENV !== "production") {
269
+ console.error("Secure Error:", SecurityUtils.sanitizeForLog(error));
270
270
  }
271
271
 
272
272
  // Return generic error to prevent information disclosure
273
273
  const secureError = new Error(fallbackMessage);
274
274
 
275
275
  // Preserve error code if it's safe
276
- if (error && typeof error.code === 'string' && !error.code.includes('_')) {
276
+ if (error && typeof error.code === "string" && !error.code.includes("_")) {
277
277
  (secureError as any).code = error.code;
278
278
  }
279
279
 
@@ -281,7 +281,7 @@ export function createSecureError(
281
281
  }
282
282
 
283
283
  // Import path for file extension checking
284
- import * as path from 'path';
284
+ import * as path from "path";
285
285
 
286
286
  /**
287
287
  * Environment-specific security settings
@@ -291,11 +291,11 @@ export function getEnvironmentSecurity(): {
291
291
  verboseErrors: boolean;
292
292
  enforceHttps: boolean;
293
293
  } {
294
- const isProduction = process.env.NODE_ENV === 'production';
294
+ const isProduction = process.env.NODE_ENV === "production";
295
295
 
296
296
  return {
297
297
  strictMode: isProduction,
298
298
  verboseErrors: !isProduction,
299
- enforceHttps: isProduction
299
+ enforceHttps: isProduction,
300
300
  };
301
301
  }
@@ -1,5 +1,5 @@
1
- import { WordPressClient } from '../client/api.js';
2
- import { getErrorMessage } from '../utils/error.js';
1
+ import { WordPressClient } from "../client/api.js";
2
+ import { getErrorMessage } from "../utils/error.js";
3
3
 
4
4
  /**
5
5
  * Service for testing WordPress client connections
@@ -10,27 +10,33 @@ export class ConnectionTester {
10
10
  * Test connections to all configured WordPress sites
11
11
  */
12
12
  public static async testClientConnections(
13
- wordpressClients: Map<string, WordPressClient>
13
+ wordpressClients: Map<string, WordPressClient>,
14
14
  ): Promise<void> {
15
- console.error('INFO: Testing connections to all configured WordPress sites...');
16
-
15
+ console.error(
16
+ "INFO: Testing connections to all configured WordPress sites...",
17
+ );
18
+
17
19
  const connectionPromises = Array.from(wordpressClients.entries()).map(
18
20
  async ([siteId, client]) => {
19
21
  try {
20
22
  await client.ping();
21
23
  console.error(`SUCCESS: Connection to site '${siteId}' successful.`);
22
24
  } catch (error) {
23
- console.error(`ERROR: Failed to connect to site '${siteId}': ${getErrorMessage(error)}`);
24
-
25
+ console.error(
26
+ `ERROR: Failed to connect to site '${siteId}': ${getErrorMessage(error)}`,
27
+ );
28
+
25
29
  if (ConnectionTester.isAuthenticationError(error)) {
26
- console.error(`Authentication may have failed for site '${siteId}'. Please check credentials.`);
30
+ console.error(
31
+ `Authentication may have failed for site '${siteId}'. Please check credentials.`,
32
+ );
27
33
  }
28
34
  }
29
- }
35
+ },
30
36
  );
31
-
37
+
32
38
  await Promise.all(connectionPromises);
33
- console.error('INFO: Connection tests complete.');
39
+ console.error("INFO: Connection tests complete.");
34
40
  }
35
41
 
36
42
  /**
@@ -40,7 +46,7 @@ export class ConnectionTester {
40
46
  if (error?.response?.status && [401, 403].includes(error.response.status)) {
41
47
  return true;
42
48
  }
43
- return error?.code === 'WORDPRESS_AUTH_ERROR';
49
+ return error?.code === "WORDPRESS_AUTH_ERROR";
44
50
  }
45
51
 
46
52
  /**
@@ -60,15 +66,15 @@ export class ConnectionTester {
60
66
  * Perform health checks for all clients
61
67
  */
62
68
  public static async healthCheckAll(
63
- wordpressClients: Map<string, WordPressClient>
69
+ wordpressClients: Map<string, WordPressClient>,
64
70
  ): Promise<Map<string, boolean>> {
65
71
  const results = new Map<string, boolean>();
66
-
72
+
67
73
  for (const [siteId, client] of wordpressClients.entries()) {
68
74
  const isHealthy = await ConnectionTester.healthCheck(client);
69
75
  results.set(siteId, isHealthy);
70
76
  }
71
-
77
+
72
78
  return results;
73
79
  }
74
80
  }
@@ -1,8 +1,8 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { WordPressClient } from '../client/api.js';
3
- import { getErrorMessage } from '../utils/error.js';
4
- import * as Tools from '../tools/index.js';
5
- import { z } from 'zod';
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { WordPressClient } from "../client/api.js";
3
+ import { getErrorMessage } from "../utils/error.js";
4
+ import * as Tools from "../tools/index.js";
5
+ import { z } from "zod";
6
6
 
7
7
  /**
8
8
  * Interface for tool definition
@@ -27,7 +27,10 @@ export class ToolRegistry {
27
27
  private server: McpServer;
28
28
  private wordpressClients: Map<string, WordPressClient>;
29
29
 
30
- constructor(server: McpServer, wordpressClients: Map<string, WordPressClient>) {
30
+ constructor(
31
+ server: McpServer,
32
+ wordpressClients: Map<string, WordPressClient>,
33
+ ) {
31
34
  this.server = server;
32
35
  this.wordpressClients = wordpressClients;
33
36
  }
@@ -39,14 +42,17 @@ export class ToolRegistry {
39
42
  // Register all tools from the tools directory
40
43
  Object.values(Tools).forEach((ToolClass) => {
41
44
  let toolInstance: any;
42
-
45
+
43
46
  // Cache and Performance tools need the clients map
44
- if (ToolClass.name === 'CacheTools' || ToolClass.name === 'PerformanceTools') {
47
+ if (
48
+ ToolClass.name === "CacheTools" ||
49
+ ToolClass.name === "PerformanceTools"
50
+ ) {
45
51
  toolInstance = new ToolClass(this.wordpressClients);
46
52
  } else {
47
53
  toolInstance = new (ToolClass as new () => any)();
48
54
  }
49
-
55
+
50
56
  const tools = toolInstance.getTools();
51
57
 
52
58
  tools.forEach((tool: ToolDefinition) => {
@@ -65,8 +71,8 @@ export class ToolRegistry {
65
71
  .string()
66
72
  .optional()
67
73
  .describe(
68
- 'The ID of the WordPress site to target (from mcp-wordpress.config.json). Required if multiple sites are configured.'
69
- )
74
+ "The ID of the WordPress site to target (from mcp-wordpress.config.json). Required if multiple sites are configured.",
75
+ ),
70
76
  };
71
77
 
72
78
  // Merge with tool-specific parameters
@@ -75,7 +81,7 @@ export class ToolRegistry {
75
81
  // Make site parameter required if multiple sites are configured
76
82
  if (this.wordpressClients.size > 1) {
77
83
  parameterSchema.site = parameterSchema.site.describe(
78
- 'The ID of the WordPress site to target (from mcp-wordpress.config.json). Required when multiple sites are configured.'
84
+ "The ID of the WordPress site to target (from mcp-wordpress.config.json). Required when multiple sites are configured.",
79
85
  );
80
86
  }
81
87
 
@@ -85,19 +91,21 @@ export class ToolRegistry {
85
91
  parameterSchema,
86
92
  async (args: any) => {
87
93
  try {
88
- const siteId = args.site || 'default';
94
+ const siteId = args.site || "default";
89
95
  const client = this.wordpressClients.get(siteId);
90
96
 
91
97
  if (!client) {
92
- const availableSites = Array.from(this.wordpressClients.keys()).join(', ');
98
+ const availableSites = Array.from(
99
+ this.wordpressClients.keys(),
100
+ ).join(", ");
93
101
  return {
94
102
  content: [
95
103
  {
96
- type: 'text' as const,
97
- text: `Error: Site with ID '${siteId}' not found. Available sites: ${availableSites}`
98
- }
104
+ type: "text" as const,
105
+ text: `Error: Site with ID '${siteId}' not found. Available sites: ${availableSites}`,
106
+ },
99
107
  ],
100
- isError: true
108
+ isError: true,
101
109
  };
102
110
  }
103
111
 
@@ -107,35 +115,38 @@ export class ToolRegistry {
107
115
  return {
108
116
  content: [
109
117
  {
110
- type: 'text' as const,
111
- text: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
112
- }
113
- ]
118
+ type: "text" as const,
119
+ text:
120
+ typeof result === "string"
121
+ ? result
122
+ : JSON.stringify(result, null, 2),
123
+ },
124
+ ],
114
125
  };
115
126
  } catch (error) {
116
127
  if (this.isAuthenticationError(error)) {
117
128
  return {
118
129
  content: [
119
130
  {
120
- type: 'text' as const,
121
- text: `Authentication failed for site '${args.site || 'default'}'. Please check your credentials.`
122
- }
131
+ type: "text" as const,
132
+ text: `Authentication failed for site '${args.site || "default"}'. Please check your credentials.`,
133
+ },
123
134
  ],
124
- isError: true
135
+ isError: true,
125
136
  };
126
137
  }
127
138
 
128
139
  return {
129
140
  content: [
130
141
  {
131
- type: 'text' as const,
132
- text: `Error: ${getErrorMessage(error)}`
133
- }
142
+ type: "text" as const,
143
+ text: `Error: ${getErrorMessage(error)}`,
144
+ },
134
145
  ],
135
- isError: true
146
+ isError: true,
136
147
  };
137
148
  }
138
- }
149
+ },
139
150
  );
140
151
  }
141
152
 
@@ -143,23 +154,25 @@ export class ToolRegistry {
143
154
  * Build Zod parameter schema from tool definition
144
155
  */
145
156
  private buildParameterSchema(tool: ToolDefinition, baseSchema: any): any {
146
- return tool.parameters?.reduce(
147
- (schema: any, param: any) => {
148
- let zodType = this.getZodTypeForParameter(param);
157
+ return (
158
+ tool.parameters?.reduce(
159
+ (schema: any, param: any) => {
160
+ let zodType = this.getZodTypeForParameter(param);
149
161
 
150
- if (param.description) {
151
- zodType = zodType.describe(param.description);
152
- }
162
+ if (param.description) {
163
+ zodType = zodType.describe(param.description);
164
+ }
153
165
 
154
- if (!param.required) {
155
- zodType = zodType.optional();
156
- }
166
+ if (!param.required) {
167
+ zodType = zodType.optional();
168
+ }
157
169
 
158
- schema[param.name] = zodType;
159
- return schema;
160
- },
161
- { ...baseSchema }
162
- ) || baseSchema;
170
+ schema[param.name] = zodType;
171
+ return schema;
172
+ },
173
+ { ...baseSchema },
174
+ ) || baseSchema
175
+ );
163
176
  }
164
177
 
165
178
  /**
@@ -167,15 +180,15 @@ export class ToolRegistry {
167
180
  */
168
181
  private getZodTypeForParameter(param: any): z.ZodType {
169
182
  switch (param.type) {
170
- case 'string':
183
+ case "string":
171
184
  return z.string();
172
- case 'number':
185
+ case "number":
173
186
  return z.number();
174
- case 'boolean':
187
+ case "boolean":
175
188
  return z.boolean();
176
- case 'array':
189
+ case "array":
177
190
  return z.array(z.string());
178
- case 'object':
191
+ case "object":
179
192
  return z.record(z.any());
180
193
  default:
181
194
  return z.string();
@@ -189,6 +202,6 @@ export class ToolRegistry {
189
202
  if (error?.response?.status && [401, 403].includes(error.response.status)) {
190
203
  return true;
191
204
  }
192
- return error?.code === 'WORDPRESS_AUTH_ERROR';
205
+ return error?.code === "WORDPRESS_AUTH_ERROR";
193
206
  }
194
207
  }
package/src/server.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  * Re-exports the main MCP server class for backward compatibility
4
4
  */
5
5
 
6
- export { default as MCPWordPressServer } from './index.js';
7
- export { default } from './index.js';
6
+ export { default as MCPWordPressServer } from "./index.js";
7
+ export { default } from "./index.js";