@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/retry.js ADDED
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Retry Logic for Transient Errors
3
+ *
4
+ * Provides exponential backoff with jitter for handling transient network
5
+ * failures and server errors (HTTP 5xx, 429, network errors).
6
+ *
7
+ * Key features:
8
+ * - Only retries transient errors (5xx, 429, network errors)
9
+ * - Permanent errors (4xx except 429) fail immediately
10
+ * - Timeout budget ensures total time never exceeds requestTimeout
11
+ * - Exponential backoff with jitter prevents thundering herd
12
+ */
13
+ /**
14
+ * Extract HTTP status code from an error.
15
+ * Handles various error formats including fetch errors and custom error objects.
16
+ */
17
+ function extractStatusCode(error) {
18
+ // Handle error objects with status property
19
+ if (error && typeof error === 'object') {
20
+ const errorObj = error;
21
+ // Direct status property (e.g., Response object or custom error)
22
+ if (typeof errorObj.status === 'number') {
23
+ return errorObj.status;
24
+ }
25
+ // Status in cause (chained errors)
26
+ if (errorObj.cause && typeof errorObj.cause === 'object') {
27
+ const cause = errorObj.cause;
28
+ if (typeof cause.status === 'number') {
29
+ return cause.status;
30
+ }
31
+ }
32
+ }
33
+ // Extract from error message patterns
34
+ if (error instanceof Error) {
35
+ const message = error.message;
36
+ // Match patterns like "Failed to fetch: 503" or "HTTP 503"
37
+ const statusMatch = message.match(/\b([45]\d{2})\b/);
38
+ if (statusMatch) {
39
+ return parseInt(statusMatch[1], 10);
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+ /**
45
+ * Extract error code from an error (e.g., ECONNRESET, ETIMEDOUT)
46
+ */
47
+ function extractErrorCode(error) {
48
+ if (error && typeof error === 'object') {
49
+ const errorObj = error;
50
+ // Direct code property (Node.js errors)
51
+ if (typeof errorObj.code === 'string') {
52
+ return errorObj.code;
53
+ }
54
+ // Code in cause (chained errors)
55
+ if (errorObj.cause && typeof errorObj.cause === 'object') {
56
+ const cause = errorObj.cause;
57
+ if (typeof cause.code === 'string') {
58
+ return cause.code;
59
+ }
60
+ }
61
+ }
62
+ // Extract from error message
63
+ if (error instanceof Error) {
64
+ const message = error.message.toUpperCase();
65
+ // Common network error codes
66
+ const networkCodes = ['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'];
67
+ for (const code of networkCodes) {
68
+ if (message.includes(code)) {
69
+ return code;
70
+ }
71
+ }
72
+ }
73
+ return null;
74
+ }
75
+ /**
76
+ * Determine if an error is retryable (transient).
77
+ *
78
+ * Retryable errors:
79
+ * - HTTP 5xx (server errors)
80
+ * - HTTP 429 (rate limited)
81
+ * - Network errors: ECONNRESET, ECONNREFUSED, ETIMEDOUT, ENOTFOUND
82
+ *
83
+ * Non-retryable errors:
84
+ * - HTTP 4xx (except 429): client errors, auth failures, validation errors
85
+ * - AbortError: user cancellation
86
+ * - Any other errors (treat as permanent)
87
+ */
88
+ export function isRetryableError(error) {
89
+ // AbortError is never retryable (user cancellation)
90
+ if (error instanceof Error && error.name === 'AbortError') {
91
+ return false;
92
+ }
93
+ // Check for HTTP status codes
94
+ const statusCode = extractStatusCode(error);
95
+ if (statusCode !== null) {
96
+ // 5xx server errors are retryable
97
+ if (statusCode >= 500 && statusCode <= 599) {
98
+ return true;
99
+ }
100
+ // 429 rate limited is retryable
101
+ if (statusCode === 429) {
102
+ return true;
103
+ }
104
+ // 4xx client errors (except 429) are NOT retryable
105
+ if (statusCode >= 400 && statusCode <= 499) {
106
+ return false;
107
+ }
108
+ }
109
+ // Check for network error codes
110
+ const errorCode = extractErrorCode(error);
111
+ if (errorCode !== null) {
112
+ const retryableCodes = ['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'];
113
+ if (retryableCodes.includes(errorCode)) {
114
+ return true;
115
+ }
116
+ }
117
+ // Unknown errors are NOT retried (conservative approach)
118
+ return false;
119
+ }
120
+ /**
121
+ * Calculate exponential backoff delay with jitter.
122
+ *
123
+ * Formula: min(maxDelay, baseDelay * 2^attempt + random(0, baseDelay))
124
+ *
125
+ * @param attempt - 0-indexed attempt number (0 for first retry, 1 for second, etc.)
126
+ * @param baseDelay - Base delay in milliseconds
127
+ * @param maxDelay - Maximum delay in milliseconds
128
+ * @returns Delay in milliseconds
129
+ */
130
+ export function calculateBackoff(attempt, baseDelay, maxDelay) {
131
+ // Exponential: baseDelay * 2^attempt
132
+ const exponentialDelay = baseDelay * Math.pow(2, attempt);
133
+ // Jitter: random value between 0 and baseDelay
134
+ const jitter = Math.random() * baseDelay;
135
+ // Total delay with jitter
136
+ const totalDelay = exponentialDelay + jitter;
137
+ // Cap at maxDelay
138
+ return Math.min(totalDelay, maxDelay);
139
+ }
140
+ /**
141
+ * Execute an operation with retry logic.
142
+ *
143
+ * @param operation - The async operation to execute
144
+ * @param options - Retry configuration
145
+ * @returns The result of the operation
146
+ * @throws The last error if all retries are exhausted or a non-retryable error occurs
147
+ */
148
+ export async function withRetry(operation, options) {
149
+ const { maxRetries, baseDelay, maxDelay, timeoutBudget, logger } = options;
150
+ const startTime = Date.now();
151
+ let lastError = null;
152
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
153
+ // Calculate remaining budget before each attempt
154
+ const elapsed = Date.now() - startTime;
155
+ const remainingBudget = timeoutBudget - elapsed;
156
+ // Check if budget is already exhausted before attempting
157
+ if (remainingBudget <= 0) {
158
+ const budgetError = new Error(`Retry timeout budget exhausted: ${Math.round(elapsed)}ms elapsed, budget was ${timeoutBudget}ms`);
159
+ if (lastError) {
160
+ budgetError.cause = lastError;
161
+ }
162
+ throw budgetError;
163
+ }
164
+ try {
165
+ // Pass context with remaining budget so operation can enforce timeout
166
+ return await operation({ remainingBudget, attempt });
167
+ }
168
+ catch (error) {
169
+ lastError = error instanceof Error ? error : new Error(String(error));
170
+ // Check if error is retryable
171
+ if (!isRetryableError(error)) {
172
+ throw lastError;
173
+ }
174
+ // Check if this was the last attempt
175
+ if (attempt >= maxRetries - 1) {
176
+ throw lastError;
177
+ }
178
+ // Calculate backoff delay
179
+ const backoffDelay = calculateBackoff(attempt, baseDelay, maxDelay);
180
+ // Re-calculate remaining budget after operation completed
181
+ const elapsedAfterOp = Date.now() - startTime;
182
+ const remainingBudgetAfterOp = timeoutBudget - elapsedAfterOp;
183
+ if (backoffDelay > remainingBudgetAfterOp) {
184
+ // Don't wait for a retry that would exceed the budget
185
+ const budgetError = new Error(`Retry timeout budget exceeded: would need ${Math.round(backoffDelay)}ms but only ${Math.round(remainingBudgetAfterOp)}ms remaining`);
186
+ // Preserve the original error as the cause
187
+ budgetError.cause = lastError;
188
+ throw budgetError;
189
+ }
190
+ // Log the retry attempt
191
+ if (logger) {
192
+ logger.warning('Retrying request after transient error', {
193
+ attempt: attempt + 1,
194
+ delay: Math.round(backoffDelay),
195
+ error: lastError.message,
196
+ remainingBudget: Math.round(remainingBudgetAfterOp),
197
+ });
198
+ }
199
+ // Wait before retrying
200
+ await new Promise(resolve => setTimeout(resolve, backoffDelay));
201
+ }
202
+ }
203
+ // Should never reach here, but TypeScript doesn't know that
204
+ throw lastError || new Error('Retry exhausted with no error captured');
205
+ }
206
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Security Utilities
3
+ *
4
+ * Shared security functions for input validation, error sanitization,
5
+ * and rate limiting.
6
+ */
7
+ /**
8
+ * Validate input arguments before forwarding to the API.
9
+ * Prevents malicious payloads and enforces reasonable limits.
10
+ * Recurses into nested objects and arrays to enforce string length and ID range checks.
11
+ * Throws McpError with INVALID_PARAMS code on validation failure.
12
+ */
13
+ export declare function validateInput(args: Record<string, unknown>, depth?: number): void;
14
+ /**
15
+ * Sanitize error messages before returning to clients.
16
+ * Removes potentially sensitive information like file paths, credentials, and stack traces.
17
+ */
18
+ export declare function sanitizeError(message: string): string;
19
+ /**
20
+ * Token bucket rate limiter to prevent API abuse.
21
+ * Throttles requests to a configurable rate per minute.
22
+ */
23
+ export declare class RateLimiter {
24
+ private tokens;
25
+ private lastRefill;
26
+ private readonly maxTokens;
27
+ private readonly refillRate;
28
+ constructor(requestsPerMinute: number);
29
+ /**
30
+ * Acquire a token, waiting if necessary.
31
+ * Returns immediately if rate limiting is disabled (maxTokens = 0).
32
+ * @param signal - Optional AbortSignal to cancel the wait
33
+ */
34
+ acquire(signal?: AbortSignal): Promise<void>;
35
+ private refill;
36
+ }
37
+ /**
38
+ * Check if a value is a valid positive integer ID
39
+ */
40
+ export declare function isValidId(value: unknown): boolean;
41
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,SAAI,GAAG,IAAI,CAwD5E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAiCrD;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,iBAAiB,EAAE,MAAM;IAOrC;;;;OAIG;IACG,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BlD,OAAO,CAAC,MAAM;CAMf;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASjD"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Security Utilities
3
+ *
4
+ * Shared security functions for input validation, error sanitization,
5
+ * and rate limiting.
6
+ */
7
+ import { McpErrorFactory } from './errors.js';
8
+ // Input validation limits
9
+ const MAX_STRING_LENGTH = 10000;
10
+ const MAX_ARRAY_ELEMENTS = 1000;
11
+ const MAX_OBJECT_DEPTH = 5;
12
+ /**
13
+ * Validate input arguments before forwarding to the API.
14
+ * Prevents malicious payloads and enforces reasonable limits.
15
+ * Recurses into nested objects and arrays to enforce string length and ID range checks.
16
+ * Throws McpError with INVALID_PARAMS code on validation failure.
17
+ */
18
+ export function validateInput(args, depth = 0) {
19
+ if (depth > MAX_OBJECT_DEPTH) {
20
+ throw McpErrorFactory.invalidParams(`Input exceeds maximum nesting depth (${MAX_OBJECT_DEPTH})`, { maxDepth: MAX_OBJECT_DEPTH });
21
+ }
22
+ for (const [key, value] of Object.entries(args)) {
23
+ // String length check
24
+ if (typeof value === 'string' && value.length > MAX_STRING_LENGTH) {
25
+ throw McpErrorFactory.invalidParams(`Parameter "${key}" exceeds maximum length (${MAX_STRING_LENGTH} characters)`, { parameter: key, maxLength: MAX_STRING_LENGTH });
26
+ }
27
+ // ID fields: accept number or numeric string, must be positive integer
28
+ if (key.endsWith('_id')) {
29
+ const numValue = typeof value === 'string' ? parseInt(value, 10) : value;
30
+ if (typeof numValue === 'number') {
31
+ if (!Number.isInteger(numValue) || numValue < 1 || numValue > Number.MAX_SAFE_INTEGER) {
32
+ throw McpErrorFactory.invalidParams(`Parameter "${key}" must be a positive integer`, {
33
+ parameter: key,
34
+ });
35
+ }
36
+ }
37
+ }
38
+ // Array validation
39
+ if (Array.isArray(value)) {
40
+ if (value.length > MAX_ARRAY_ELEMENTS) {
41
+ throw McpErrorFactory.invalidParams(`Parameter "${key}" has too many elements (max ${MAX_ARRAY_ELEMENTS})`, { parameter: key, maxElements: MAX_ARRAY_ELEMENTS, actualElements: value.length });
42
+ }
43
+ // Validate array elements (strings and nested objects)
44
+ for (const item of value) {
45
+ if (typeof item === 'string' && item.length > MAX_STRING_LENGTH) {
46
+ throw McpErrorFactory.invalidParams(`Element in "${key}" exceeds maximum length (${MAX_STRING_LENGTH} characters)`, { parameter: key, maxLength: MAX_STRING_LENGTH });
47
+ }
48
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
49
+ validateInput(item, depth + 1);
50
+ }
51
+ }
52
+ }
53
+ // Nested object: recurse to validate contents (string lengths, ID ranges, depth)
54
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
55
+ validateInput(value, depth + 1);
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Sanitize error messages before returning to clients.
61
+ * Removes potentially sensitive information like file paths, credentials, and stack traces.
62
+ */
63
+ export function sanitizeError(message) {
64
+ return (message
65
+ // Remove absolute file paths (Unix: /home/..., /var/..., macOS: /Users/...)
66
+ .replace(/\/(Users|home|var|tmp|etc|usr|opt)\/[\w\-./]+/gi, '[path]')
67
+ // Remove Windows paths
68
+ .replace(/[A-Z]:\\[\w\-\\./]+/gi, '[path]')
69
+ // Remove credentials in URLs (user:pass@host)
70
+ .replace(/(https?:\/\/)[^:]+:[^@]+@/g, '$1[redacted]@')
71
+ // Remove Bearer tokens (Authorization: Bearer xxx)
72
+ .replace(/Bearer\s+[\w\-._~+/]+=*/gi, 'Bearer [redacted]')
73
+ // Remove potential tokens/keys in key=value patterns (handles quoted values with spaces)
74
+ // Matches: TOKEN=xxx, _TOKEN=xxx, MAINWP_TOKEN=xxx, password: "xxx", etc.
75
+ .replace(/\b(\w*(?:token|password|secret|key|auth|credential))[=:]\s*"[^"]*"/gi, '$1=[redacted]')
76
+ .replace(/\b(\w*(?:token|password|secret|key|auth|credential))[=:]\s*'[^']*'/gi, '$1=[redacted]')
77
+ .replace(/\b(\w*(?:token|password|secret|key|auth|credential))[=:]\s*[\w\-._~+/]+=*/gi, '$1=[redacted]')
78
+ // Remove stack traces (at Function.name (file:line:col))
79
+ .replace(/\s+at\s+.+\(.+:\d+:\d+\)/g, '')
80
+ // Remove Node.js internal paths
81
+ .replace(/\(node:[\w]+:\d+:\d+\)/g, '')
82
+ // Truncate to reasonable length
83
+ .slice(0, 500)
84
+ .trim());
85
+ }
86
+ /**
87
+ * Token bucket rate limiter to prevent API abuse.
88
+ * Throttles requests to a configurable rate per minute.
89
+ */
90
+ export class RateLimiter {
91
+ tokens;
92
+ lastRefill;
93
+ maxTokens;
94
+ refillRate; // tokens per ms
95
+ constructor(requestsPerMinute) {
96
+ this.maxTokens = requestsPerMinute;
97
+ this.tokens = requestsPerMinute;
98
+ this.refillRate = requestsPerMinute / 60000;
99
+ this.lastRefill = Date.now();
100
+ }
101
+ /**
102
+ * Acquire a token, waiting if necessary.
103
+ * Returns immediately if rate limiting is disabled (maxTokens = 0).
104
+ * @param signal - Optional AbortSignal to cancel the wait
105
+ */
106
+ async acquire(signal) {
107
+ if (this.maxTokens === 0)
108
+ return; // Disabled
109
+ this.refill();
110
+ if (this.tokens < 1) {
111
+ if (signal?.aborted) {
112
+ throw new Error('Rate limiter acquire aborted');
113
+ }
114
+ const waitTime = Math.ceil((1 - this.tokens) / this.refillRate);
115
+ await new Promise((resolve, reject) => {
116
+ const timer = setTimeout(() => {
117
+ cleanup();
118
+ resolve();
119
+ }, waitTime);
120
+ const onAbort = () => {
121
+ clearTimeout(timer);
122
+ cleanup();
123
+ reject(new Error('Rate limiter acquire aborted'));
124
+ };
125
+ const cleanup = () => {
126
+ signal?.removeEventListener('abort', onAbort);
127
+ };
128
+ signal?.addEventListener('abort', onAbort, { once: true });
129
+ });
130
+ this.refill();
131
+ }
132
+ this.tokens -= 1;
133
+ }
134
+ refill() {
135
+ const now = Date.now();
136
+ const elapsed = now - this.lastRefill;
137
+ this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate);
138
+ this.lastRefill = now;
139
+ }
140
+ }
141
+ /**
142
+ * Check if a value is a valid positive integer ID
143
+ */
144
+ export function isValidId(value) {
145
+ if (typeof value === 'number') {
146
+ return Number.isInteger(value) && value >= 1 && value <= Number.MAX_SAFE_INTEGER;
147
+ }
148
+ if (typeof value === 'string') {
149
+ const num = parseInt(value, 10);
150
+ return !isNaN(num) && num >= 1 && num <= Number.MAX_SAFE_INTEGER;
151
+ }
152
+ return false;
153
+ }
154
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * MCP Tool Conversion
3
+ *
4
+ * Converts MainWP Abilities to MCP Tool definitions and handles
5
+ * tool execution by forwarding to the Abilities API.
6
+ */
7
+ import { Tool, TextContent } from '@modelcontextprotocol/sdk/types.js';
8
+ import { AbilityAnnotations } from './abilities.js';
9
+ import { Config, SchemaVerbosity } from './config.js';
10
+ import { Logger } from './logging.js';
11
+ /**
12
+ * Check whether an error represents an idempotent no-op (already in desired state).
13
+ * Only matches 4xx HTTP errors with a recognized no-op error code.
14
+ * @internal
15
+ */
16
+ export declare function isNoOpError(error: unknown): boolean;
17
+ /**
18
+ * Get the current cumulative session data usage in bytes and the configured limit.
19
+ */
20
+ export declare function getSessionDataUsage(config: Config): {
21
+ used: number;
22
+ limit: number;
23
+ };
24
+ /**
25
+ * Reset the cumulative session data counter to zero.
26
+ */
27
+ export declare function resetSessionData(): void;
28
+ /**
29
+ * Clear pending previews (for testing only).
30
+ * @internal
31
+ */
32
+ export declare function clearPendingPreviews(): void;
33
+ /**
34
+ * Options for tool execution
35
+ */
36
+ export interface ExecuteToolOptions {
37
+ /** AbortSignal for cancellation support */
38
+ signal?: AbortSignal;
39
+ }
40
+ /**
41
+ * Generate contextual LLM instruction text from ability metadata.
42
+ *
43
+ * Produces safety guidance that tells the AI how to use a tool correctly:
44
+ * preview-first workflows, dry-run suggestions, or read-only assurance.
45
+ * API-provided instructions are prepended (they take priority).
46
+ * @internal
47
+ */
48
+ export declare function generateInstructions(meta: AbilityAnnotations | undefined, hasDryRun: boolean, hasConfirm: boolean): string;
49
+ /**
50
+ * Build safety tag string for tool descriptions.
51
+ *
52
+ * Standard mode: verbose tags like `[DESTRUCTIVE, Requires two-step confirmation]`
53
+ * Compact mode: short tags like `[destructive, confirm]`
54
+ * @internal
55
+ */
56
+ export declare function buildSafetyTags(meta: AbilityAnnotations | undefined, hasDryRun: boolean, hasConfirm: boolean, verbosity: SchemaVerbosity): string;
57
+ /**
58
+ * Clear the cached tool list (for testing).
59
+ * @internal
60
+ */
61
+ export declare function clearToolsCache(): void;
62
+ /**
63
+ * Fetch all MainWP abilities and convert them to MCP tools
64
+ *
65
+ * Applies optional filtering based on config:
66
+ * - allowedTools: If set, only include tools in this list
67
+ * - blockedTools: If set, exclude tools in this list
68
+ *
69
+ * Caches the converted tool list by abilities array reference and config
70
+ * fingerprint. fetchAbilities() returns the same cached array while valid,
71
+ * so reference equality is a reliable cache key.
72
+ *
73
+ * @param config - Server configuration
74
+ * @param logger - Optional structured logger for filtering/verbosity messages
75
+ */
76
+ export declare function getTools(config: Config, logger?: Logger): Promise<Tool[]>;
77
+ export { abilityNameToToolName, toolNameToAbilityName } from './naming.js';
78
+ /**
79
+ * Execute an MCP tool call by forwarding to the corresponding ability
80
+ */
81
+ export declare function executeTool(config: Config, toolName: string, args: Record<string, unknown>, logger: Logger, options?: ExecuteToolOptions): Promise<TextContent[]>;
82
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAEL,kBAAkB,EAInB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,eAAe,EAAc,MAAM,aAAa,CAAC;AAGlE,OAAO,EAAE,MAAM,EAAiB,MAAM,cAAc,CAAC;AAsErD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEnF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAG3C;AA6DD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAmKD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,GAAG,SAAS,EACpC,SAAS,EAAE,OAAO,EAClB,UAAU,EAAE,OAAO,GAClB,MAAM,CAyBR;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,kBAAkB,GAAG,SAAS,EACpC,SAAS,EAAE,OAAO,EAClB,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,eAAe,GACzB,MAAM,CAqBR;AA6GD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAmD/E;AAGD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAE3E;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,WAAW,EAAE,CAAC,CAwYxB"}