@mcpc-tech/core 0.3.9 → 0.3.11

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.
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/search-tool.ts
31
+ var search_tool_exports = {};
32
+ __export(search_tool_exports, {
33
+ createPlugin: () => createPlugin,
34
+ createSearchPlugin: () => createSearchPlugin,
35
+ default: () => search_tool_default
36
+ });
37
+ module.exports = __toCommonJS(search_tool_exports);
38
+ var import_ripgrep_napi = __toESM(require("@mcpc-tech/ripgrep-napi"), 1);
39
+ var import_node_os = require("node:os");
40
+
41
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/utils/schema.js
42
+ var schemaSymbol = Symbol.for("mcpc.schema");
43
+ var vercelSchemaSymbol = Symbol.for("vercel.ai.schema");
44
+ var validatorSymbol = Symbol.for("mcpc.validator");
45
+ function jsonSchema(schema, options = {}) {
46
+ if (isWrappedSchema(schema)) {
47
+ return schema;
48
+ }
49
+ return {
50
+ [schemaSymbol]: true,
51
+ [validatorSymbol]: true,
52
+ _type: void 0,
53
+ jsonSchema: schema,
54
+ validate: options.validate
55
+ };
56
+ }
57
+ function isWrappedSchema(value) {
58
+ return typeof value === "object" && value !== null && (schemaSymbol in value && value[schemaSymbol] === true || vercelSchemaSymbol in value && value[vercelSchemaSymbol] === true);
59
+ }
60
+
61
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/search-tool.ts
62
+ var import_node_path = require("node:path");
63
+ var import_node_path2 = require("node:path");
64
+ function createSearchPlugin(options = {}) {
65
+ const maxResults = options.maxResults || 20;
66
+ const maxOutputSize = options.maxOutputSize || 5e3;
67
+ const allowedSearchDir = options.allowedDir || (0, import_node_os.tmpdir)();
68
+ const timeoutMs = options.timeoutMs || 3e4;
69
+ const global = options.global ?? true;
70
+ const activeTimeouts = /* @__PURE__ */ new Set();
71
+ return {
72
+ name: "plugin-search",
73
+ version: "1.0.0",
74
+ configureServer: (server) => {
75
+ const defaultDescription = `Search for text patterns in files and directories. Use this to find specific content, code, or information within files. Provide a simple literal string or a regular expression. If your pattern is a regex, ensure it's valid; otherwise use quotes or escape special characters to treat it as a literal string.
76
+ Only search within the allowed directory: ${allowedSearchDir}`;
77
+ const toolDescription = options.toolDescription || defaultDescription;
78
+ server.tool(
79
+ "search-tool-result",
80
+ toolDescription,
81
+ jsonSchema({
82
+ type: "object",
83
+ properties: {
84
+ pattern: {
85
+ type: "string",
86
+ description: "Text to search for. Can be a plain string or a regular expression. For regexes, don't include delimiters (e.g. use `^foo` not `/^foo/`). If you get a regex parse error, try escaping special chars or using a simpler literal search."
87
+ },
88
+ path: {
89
+ type: "string",
90
+ description: "File or folder path to limit the search (optional). Must be within the allowed directory."
91
+ },
92
+ maxResults: {
93
+ type: "number",
94
+ description: "Maximum number of matches to return (optional). Lower this to reduce output size and runtime."
95
+ }
96
+ },
97
+ required: ["pattern"]
98
+ }),
99
+ async (args) => {
100
+ const isBroad = (raw) => {
101
+ const t = (raw ?? "").trim();
102
+ if (!t) return true;
103
+ if (/^[*.\s]{2,}$/.test(t)) return true;
104
+ if (t === ".*" || t === "." || t === "^.*$") return true;
105
+ if (/^\^?\.\*\$?$/.test(t)) return true;
106
+ if (/^\\s?\*+$/.test(t)) return true;
107
+ return false;
108
+ };
109
+ const appendMatchSafely = (current, addition, limit) => {
110
+ if ((current + addition).length > limit) {
111
+ return { current, added: false };
112
+ }
113
+ return { current: current + addition, added: true };
114
+ };
115
+ let timeoutId;
116
+ try {
117
+ const requestedPath = args.path || allowedSearchDir;
118
+ const limit = args.maxResults || maxResults;
119
+ if (args.path) {
120
+ const resolvedRequested = (0, import_node_path.resolve)(args.path);
121
+ const resolvedAllowed = (0, import_node_path.resolve)(allowedSearchDir);
122
+ const relativePath = (0, import_node_path2.relative)(resolvedAllowed, resolvedRequested);
123
+ if (relativePath && relativePath.startsWith("..")) {
124
+ return {
125
+ content: [
126
+ {
127
+ type: "text",
128
+ text: `\u274C Path "${args.path}" not allowed. Must be within: ${allowedSearchDir}`
129
+ }
130
+ ],
131
+ isError: true
132
+ };
133
+ }
134
+ }
135
+ const searchPath = requestedPath;
136
+ const rawPattern = args.pattern ?? "";
137
+ if (isBroad(rawPattern)) {
138
+ return {
139
+ content: [
140
+ {
141
+ type: "text",
142
+ text: `\u274C Search pattern too broad: "${rawPattern}"
143
+ Provide a more specific pattern (e.g. include a filename fragment, a keyword, or limit with the "path" parameter). Avoid patterns that only contain wildcards like "*" or ".*".`
144
+ }
145
+ ],
146
+ isError: true
147
+ };
148
+ }
149
+ const timeoutPromise = new Promise((_, reject) => {
150
+ timeoutId = setTimeout(() => {
151
+ reject(new Error(`Search timeout after ${timeoutMs}ms`));
152
+ }, timeoutMs);
153
+ activeTimeouts.add(timeoutId);
154
+ });
155
+ const searchPromise = new Promise((resolve2, reject) => {
156
+ try {
157
+ const result2 = import_ripgrep_napi.default.search(args.pattern, [searchPath]);
158
+ resolve2(result2);
159
+ } catch (error) {
160
+ reject(error);
161
+ }
162
+ });
163
+ const result = await Promise.race([
164
+ searchPromise,
165
+ timeoutPromise
166
+ ]);
167
+ if (timeoutId) {
168
+ clearTimeout(timeoutId);
169
+ activeTimeouts.delete(timeoutId);
170
+ }
171
+ if (!result.success || !result.matches?.length) {
172
+ return {
173
+ content: [
174
+ {
175
+ type: "text",
176
+ text: `No matches found for: "${args.pattern}"
177
+
178
+ Try:
179
+ - **Simpler pattern** or \`*\`
180
+ - Check if files exist in: ${searchPath}
181
+ - Use specific file path`
182
+ }
183
+ ]
184
+ };
185
+ }
186
+ const matches = result.matches.slice(0, limit);
187
+ let output = `Found ${result.matches.length} matches (showing up to ${matches.length}):
188
+
189
+ `;
190
+ let matchesIncluded = 0;
191
+ for (const match of matches) {
192
+ const baseMatchText = `**${match.path}:${match.lineNumber}**
193
+ `;
194
+ const fullMatchText = `${baseMatchText}\`\`\`
195
+ ${match.line}
196
+ \`\`\`
197
+
198
+ `;
199
+ const res = appendMatchSafely(
200
+ output,
201
+ fullMatchText,
202
+ maxOutputSize
203
+ );
204
+ if (!res.added) {
205
+ if (matchesIncluded === 0) {
206
+ const remainingSpace = maxOutputSize - output.length - 100;
207
+ if (remainingSpace > 50) {
208
+ const truncatedLine = match.line.slice(0, remainingSpace);
209
+ output += `${baseMatchText}\`\`\`
210
+ ${truncatedLine}...
211
+ \`\`\`
212
+
213
+ `;
214
+ output += `\u26A0\uFE0F Content truncated
215
+ `;
216
+ matchesIncluded++;
217
+ } else {
218
+ output += `\u26A0\uFE0F Content too large, use specific file path
219
+ `;
220
+ }
221
+ }
222
+ break;
223
+ }
224
+ output = res.current;
225
+ matchesIncluded++;
226
+ }
227
+ if (matchesIncluded < matches.length) {
228
+ output += `
229
+ \u26A0\uFE0F Showing ${matchesIncluded}/${matches.length} matches (size limit)
230
+ `;
231
+ output += `
232
+ For more results:
233
+ `;
234
+ output += `- Use specific pattern: "${args.pattern} keyword"
235
+ `;
236
+ output += `- Search specific file: {"pattern": "${args.pattern}", "path": "/file.txt"}
237
+ `;
238
+ output += `- Use fewer results: {"maxResults": 5}`;
239
+ }
240
+ return {
241
+ content: [
242
+ {
243
+ type: "text",
244
+ text: output
245
+ }
246
+ ]
247
+ };
248
+ } catch (error) {
249
+ if (timeoutId) {
250
+ clearTimeout(timeoutId);
251
+ activeTimeouts.delete(timeoutId);
252
+ }
253
+ const errorMsg = error instanceof Error ? error.message : String(error);
254
+ const isTimeout = errorMsg.includes("timeout");
255
+ return {
256
+ content: [
257
+ {
258
+ type: "text",
259
+ text: `Search error: ${errorMsg}
260
+
261
+ ${isTimeout ? `Timeout after ${timeoutMs}ms. Try simpler pattern or smaller directory.` : `Check pattern syntax or directory exists.`}`
262
+ }
263
+ ]
264
+ };
265
+ }
266
+ },
267
+ { internal: !global }
268
+ );
269
+ },
270
+ dispose: () => {
271
+ for (const timeoutId of activeTimeouts) {
272
+ clearTimeout(timeoutId);
273
+ }
274
+ activeTimeouts.clear();
275
+ }
276
+ };
277
+ }
278
+ var defaultSearchPlugin = createSearchPlugin({
279
+ global: true,
280
+ maxResults: 20,
281
+ maxOutputSize: 5e3,
282
+ caseSensitive: false,
283
+ timeoutMs: 3e4
284
+ });
285
+ var createPlugin = createSearchPlugin;
286
+ var search_tool_default = defaultSearchPlugin;
287
+ // Annotate the CommonJS export names for ESM import in node:
288
+ 0 && (module.exports = {
289
+ createPlugin,
290
+ createSearchPlugin
291
+ });
@@ -40,10 +40,12 @@ function createSearchPlugin(options = {}) {
40
40
  name: "plugin-search",
41
41
  version: "1.0.0",
42
42
  configureServer: (server) => {
43
+ const defaultDescription = `Search for text patterns in files and directories. Use this to find specific content, code, or information within files. Provide a simple literal string or a regular expression. If your pattern is a regex, ensure it's valid; otherwise use quotes or escape special characters to treat it as a literal string.
44
+ Only search within the allowed directory: ${allowedSearchDir}`;
45
+ const toolDescription = options.toolDescription || defaultDescription;
43
46
  server.tool(
44
47
  "search-tool-result",
45
- `Search for text patterns in files and directories. Use this to find specific content, code, or information within files. Provide a simple literal string or a regular expression. If your pattern is a regex, ensure it's valid; otherwise use quotes or escape special characters to treat it as a literal string.
46
- Only search within the allowed directory: ${allowedSearchDir}`,
48
+ toolDescription,
47
49
  jsonSchema({
48
50
  type: "object",
49
51
  properties: {
package/plugins.cjs ADDED
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // __mcpc__core_latest/node_modules/@mcpc/core/plugins.ts
31
+ var plugins_exports = {};
32
+ __export(plugins_exports, {
33
+ createLargeResultPlugin: () => createLargeResultPlugin,
34
+ createSearchPlugin: () => createSearchPlugin,
35
+ defaultLargeResultPlugin: () => large_result_default,
36
+ defaultSearchPlugin: () => search_tool_default
37
+ });
38
+ module.exports = __toCommonJS(plugins_exports);
39
+
40
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/search-tool.js
41
+ var import_ripgrep_napi = __toESM(require("@mcpc-tech/ripgrep-napi"), 1);
42
+ var import_node_os = require("node:os");
43
+
44
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/utils/schema.js
45
+ var schemaSymbol = Symbol.for("mcpc.schema");
46
+ var vercelSchemaSymbol = Symbol.for("vercel.ai.schema");
47
+ var validatorSymbol = Symbol.for("mcpc.validator");
48
+ function jsonSchema(schema, options = {}) {
49
+ if (isWrappedSchema(schema)) {
50
+ return schema;
51
+ }
52
+ return {
53
+ [schemaSymbol]: true,
54
+ [validatorSymbol]: true,
55
+ _type: void 0,
56
+ jsonSchema: schema,
57
+ validate: options.validate
58
+ };
59
+ }
60
+ function isWrappedSchema(value) {
61
+ return typeof value === "object" && value !== null && (schemaSymbol in value && value[schemaSymbol] === true || vercelSchemaSymbol in value && value[vercelSchemaSymbol] === true);
62
+ }
63
+
64
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/search-tool.js
65
+ var import_node_path = require("node:path");
66
+ var import_node_path2 = require("node:path");
67
+ function createSearchPlugin(options = {}) {
68
+ const maxResults = options.maxResults || 20;
69
+ const maxOutputSize = options.maxOutputSize || 5e3;
70
+ const allowedSearchDir = options.allowedDir || (0, import_node_os.tmpdir)();
71
+ const timeoutMs = options.timeoutMs || 3e4;
72
+ const global = options.global ?? true;
73
+ const activeTimeouts = /* @__PURE__ */ new Set();
74
+ return {
75
+ name: "plugin-search",
76
+ version: "1.0.0",
77
+ configureServer: (server) => {
78
+ const defaultDescription = `Search for text patterns in files and directories. Use this to find specific content, code, or information within files. Provide a simple literal string or a regular expression. If your pattern is a regex, ensure it's valid; otherwise use quotes or escape special characters to treat it as a literal string.
79
+ Only search within the allowed directory: ${allowedSearchDir}`;
80
+ const toolDescription = options.toolDescription || defaultDescription;
81
+ server.tool("search-tool-result", toolDescription, jsonSchema({
82
+ type: "object",
83
+ properties: {
84
+ pattern: {
85
+ type: "string",
86
+ description: "Text to search for. Can be a plain string or a regular expression. For regexes, don't include delimiters (e.g. use `^foo` not `/^foo/`). If you get a regex parse error, try escaping special chars or using a simpler literal search."
87
+ },
88
+ path: {
89
+ type: "string",
90
+ description: "File or folder path to limit the search (optional). Must be within the allowed directory."
91
+ },
92
+ maxResults: {
93
+ type: "number",
94
+ description: "Maximum number of matches to return (optional). Lower this to reduce output size and runtime."
95
+ }
96
+ },
97
+ required: [
98
+ "pattern"
99
+ ]
100
+ }), async (args) => {
101
+ const isBroad = (raw) => {
102
+ const t = (raw ?? "").trim();
103
+ if (!t) return true;
104
+ if (/^[*.\s]{2,}$/.test(t)) return true;
105
+ if (t === ".*" || t === "." || t === "^.*$") return true;
106
+ if (/^\^?\.\*\$?$/.test(t)) return true;
107
+ if (/^\\s?\*+$/.test(t)) return true;
108
+ return false;
109
+ };
110
+ const appendMatchSafely = (current, addition, limit) => {
111
+ if ((current + addition).length > limit) {
112
+ return {
113
+ current,
114
+ added: false
115
+ };
116
+ }
117
+ return {
118
+ current: current + addition,
119
+ added: true
120
+ };
121
+ };
122
+ let timeoutId;
123
+ try {
124
+ const requestedPath = args.path || allowedSearchDir;
125
+ const limit = args.maxResults || maxResults;
126
+ if (args.path) {
127
+ const resolvedRequested = (0, import_node_path.resolve)(args.path);
128
+ const resolvedAllowed = (0, import_node_path.resolve)(allowedSearchDir);
129
+ const relativePath = (0, import_node_path2.relative)(resolvedAllowed, resolvedRequested);
130
+ if (relativePath && relativePath.startsWith("..")) {
131
+ return {
132
+ content: [
133
+ {
134
+ type: "text",
135
+ text: `\u274C Path "${args.path}" not allowed. Must be within: ${allowedSearchDir}`
136
+ }
137
+ ],
138
+ isError: true
139
+ };
140
+ }
141
+ }
142
+ const searchPath = requestedPath;
143
+ const rawPattern = args.pattern ?? "";
144
+ if (isBroad(rawPattern)) {
145
+ return {
146
+ content: [
147
+ {
148
+ type: "text",
149
+ text: `\u274C Search pattern too broad: "${rawPattern}"
150
+ Provide a more specific pattern (e.g. include a filename fragment, a keyword, or limit with the "path" parameter). Avoid patterns that only contain wildcards like "*" or ".*".`
151
+ }
152
+ ],
153
+ isError: true
154
+ };
155
+ }
156
+ const timeoutPromise = new Promise((_, reject) => {
157
+ timeoutId = setTimeout(() => {
158
+ reject(new Error(`Search timeout after ${timeoutMs}ms`));
159
+ }, timeoutMs);
160
+ activeTimeouts.add(timeoutId);
161
+ });
162
+ const searchPromise = new Promise((resolve2, reject) => {
163
+ try {
164
+ const result2 = import_ripgrep_napi.default.search(args.pattern, [
165
+ searchPath
166
+ ]);
167
+ resolve2(result2);
168
+ } catch (error) {
169
+ reject(error);
170
+ }
171
+ });
172
+ const result = await Promise.race([
173
+ searchPromise,
174
+ timeoutPromise
175
+ ]);
176
+ if (timeoutId) {
177
+ clearTimeout(timeoutId);
178
+ activeTimeouts.delete(timeoutId);
179
+ }
180
+ if (!result.success || !result.matches?.length) {
181
+ return {
182
+ content: [
183
+ {
184
+ type: "text",
185
+ text: `No matches found for: "${args.pattern}"
186
+
187
+ Try:
188
+ - **Simpler pattern** or \`*\`
189
+ - Check if files exist in: ${searchPath}
190
+ - Use specific file path`
191
+ }
192
+ ]
193
+ };
194
+ }
195
+ const matches = result.matches.slice(0, limit);
196
+ let output = `Found ${result.matches.length} matches (showing up to ${matches.length}):
197
+
198
+ `;
199
+ let matchesIncluded = 0;
200
+ for (const match of matches) {
201
+ const baseMatchText = `**${match.path}:${match.lineNumber}**
202
+ `;
203
+ const fullMatchText = `${baseMatchText}\`\`\`
204
+ ${match.line}
205
+ \`\`\`
206
+
207
+ `;
208
+ const res = appendMatchSafely(output, fullMatchText, maxOutputSize);
209
+ if (!res.added) {
210
+ if (matchesIncluded === 0) {
211
+ const remainingSpace = maxOutputSize - output.length - 100;
212
+ if (remainingSpace > 50) {
213
+ const truncatedLine = match.line.slice(0, remainingSpace);
214
+ output += `${baseMatchText}\`\`\`
215
+ ${truncatedLine}...
216
+ \`\`\`
217
+
218
+ `;
219
+ output += `\u26A0\uFE0F Content truncated
220
+ `;
221
+ matchesIncluded++;
222
+ } else {
223
+ output += `\u26A0\uFE0F Content too large, use specific file path
224
+ `;
225
+ }
226
+ }
227
+ break;
228
+ }
229
+ output = res.current;
230
+ matchesIncluded++;
231
+ }
232
+ if (matchesIncluded < matches.length) {
233
+ output += `
234
+ \u26A0\uFE0F Showing ${matchesIncluded}/${matches.length} matches (size limit)
235
+ `;
236
+ output += `
237
+ For more results:
238
+ `;
239
+ output += `- Use specific pattern: "${args.pattern} keyword"
240
+ `;
241
+ output += `- Search specific file: {"pattern": "${args.pattern}", "path": "/file.txt"}
242
+ `;
243
+ output += `- Use fewer results: {"maxResults": 5}`;
244
+ }
245
+ return {
246
+ content: [
247
+ {
248
+ type: "text",
249
+ text: output
250
+ }
251
+ ]
252
+ };
253
+ } catch (error) {
254
+ if (timeoutId) {
255
+ clearTimeout(timeoutId);
256
+ activeTimeouts.delete(timeoutId);
257
+ }
258
+ const errorMsg = error instanceof Error ? error.message : String(error);
259
+ const isTimeout = errorMsg.includes("timeout");
260
+ return {
261
+ content: [
262
+ {
263
+ type: "text",
264
+ text: `Search error: ${errorMsg}
265
+
266
+ ${isTimeout ? `Timeout after ${timeoutMs}ms. Try simpler pattern or smaller directory.` : `Check pattern syntax or directory exists.`}`
267
+ }
268
+ ]
269
+ };
270
+ }
271
+ }, {
272
+ internal: !global
273
+ });
274
+ },
275
+ dispose: () => {
276
+ for (const timeoutId of activeTimeouts) {
277
+ clearTimeout(timeoutId);
278
+ }
279
+ activeTimeouts.clear();
280
+ }
281
+ };
282
+ }
283
+ var defaultSearchPlugin = createSearchPlugin({
284
+ global: true,
285
+ maxResults: 20,
286
+ maxOutputSize: 5e3,
287
+ caseSensitive: false,
288
+ timeoutMs: 3e4
289
+ });
290
+ var search_tool_default = defaultSearchPlugin;
291
+
292
+ // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/large-result.js
293
+ var import_promises = require("node:fs/promises");
294
+ var import_node_path3 = require("node:path");
295
+ var import_node_os2 = require("node:os");
296
+ function createLargeResultPlugin(options = {}) {
297
+ const maxSize = options.maxSize || 8e3;
298
+ const previewSize = options.previewSize || 4e3;
299
+ let tempDir = options.tempDir || null;
300
+ const configuredServers = /* @__PURE__ */ new Map();
301
+ const defaultSearchDescription = `Search within large tool result files that were saved due to size limits. Use when: a tool result was saved to file because it exceeded the context limit. Do NOT use this tool before calling the actual tool first. Provide specific keywords or patterns related to the content you're looking for.`;
302
+ const searchConfig = {
303
+ maxResults: options.search?.maxResults || 15,
304
+ maxOutputSize: options.search?.maxOutputSize || 4e3,
305
+ toolDescription: options.search?.toolDescription || defaultSearchDescription,
306
+ global: true
307
+ };
308
+ return {
309
+ name: "plugin-large-result-handler",
310
+ version: "1.0.0",
311
+ dependencies: [],
312
+ configureServer: async (server) => {
313
+ if (!configuredServers.has(server)) {
314
+ const searchPlugin = createSearchPlugin(searchConfig);
315
+ await server.addPlugin(searchPlugin);
316
+ configuredServers.set(server, true);
317
+ }
318
+ },
319
+ transformTool: (tool, context) => {
320
+ const originalExecute = tool.execute;
321
+ tool.execute = async (args) => {
322
+ try {
323
+ const result = await originalExecute(args);
324
+ const resultText = JSON.stringify(result);
325
+ if (resultText.length <= maxSize) {
326
+ return result;
327
+ }
328
+ if (!tempDir) {
329
+ tempDir = await (0, import_promises.mkdtemp)((0, import_node_path3.join)((0, import_node_os2.tmpdir)(), "mcpc-results-"));
330
+ }
331
+ const safeToolName = encodeURIComponent(context.toolName ?? "tool");
332
+ const fileName = `${safeToolName}-${Date.now()}.txt`;
333
+ const filePath = (0, import_node_path3.join)(tempDir, fileName);
334
+ await (0, import_promises.writeFile)(filePath, resultText);
335
+ const preview = resultText.slice(0, previewSize);
336
+ const sizeKB = (resultText.length / 1024).toFixed(1);
337
+ return {
338
+ content: [
339
+ {
340
+ type: "text",
341
+ text: `**Result too large (${resultText.length} chars), saved to file**
342
+
343
+ \u{1F4C1} **File:** ${filePath}
344
+ \u{1F4CA} **Size:** ${sizeKB} KB
345
+
346
+ **Preview (${previewSize} chars):**
347
+ \`\`\`
348
+ ${preview}
349
+ \`\`\`
350
+
351
+ **To read/understand the full content:**
352
+ - Use the \`search-tool-result\` tool with pattern: \`search-tool-result {"pattern": "your-search-term"}\`
353
+ - Search supports regex patterns for advanced queries`
354
+ }
355
+ ]
356
+ };
357
+ } catch (error) {
358
+ const errorMsg = error instanceof Error ? error.message : String(error);
359
+ console.error(`Large result plugin error for ${context.toolName}: ${errorMsg}`);
360
+ throw error;
361
+ }
362
+ };
363
+ return tool;
364
+ },
365
+ dispose: () => {
366
+ configuredServers.clear();
367
+ tempDir = null;
368
+ }
369
+ };
370
+ }
371
+ var defaultLargeResultPlugin = createLargeResultPlugin({
372
+ maxSize: 8e3,
373
+ previewSize: 4e3
374
+ });
375
+ var large_result_default = defaultLargeResultPlugin;
376
+ // Annotate the CommonJS export names for ESM import in node:
377
+ 0 && (module.exports = {
378
+ createLargeResultPlugin,
379
+ createSearchPlugin,
380
+ defaultLargeResultPlugin,
381
+ defaultSearchPlugin
382
+ });