@juspay/neurolink 8.23.0 → 8.23.2
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.
- package/CHANGELOG.md +12 -0
- package/dist/lib/mcp/externalServerManager.js +31 -1
- package/dist/lib/types/externalMcp.d.ts +2 -0
- package/dist/lib/types/mcpTypes.d.ts +1 -0
- package/dist/lib/utils/pdfProcessor.js +4 -0
- package/dist/mcp/externalServerManager.js +31 -1
- package/dist/types/externalMcp.d.ts +2 -0
- package/dist/types/mcpTypes.d.ts +1 -0
- package/dist/utils/pdfProcessor.js +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [8.23.2](https://github.com/juspay/neurolink/compare/v8.23.1...v8.23.2) (2025-12-27)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **(format):** Add format validation to PDF image conversion ([bdd3285](https://github.com/juspay/neurolink/commit/bdd32855daa25d1e0fd1e94db6d97055fd5bd478))
|
|
6
|
+
|
|
7
|
+
## [8.23.1](https://github.com/juspay/neurolink/compare/v8.23.0...v8.23.1) (2025-12-24)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **(mcp):** Added Blocked Tool Support ([852d079](https://github.com/juspay/neurolink/commit/852d079371878d2a808ef6c0dc76103eb1d13a83))
|
|
12
|
+
|
|
1
13
|
## [8.23.0](https://github.com/juspay/neurolink/compare/v8.22.0...v8.23.0) (2025-12-23)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -57,6 +57,15 @@ function isValidExternalMCPServerConfig(config) {
|
|
|
57
57
|
return false;
|
|
58
58
|
}
|
|
59
59
|
const record = config;
|
|
60
|
+
// Validate blockedTools array contains only strings
|
|
61
|
+
if (record.blockedTools !== undefined) {
|
|
62
|
+
if (!Array.isArray(record.blockedTools)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (!record.blockedTools.every((item) => typeof item === "string")) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
60
69
|
return (typeof record.command === "string" &&
|
|
61
70
|
(record.args === undefined || Array.isArray(record.args)) &&
|
|
62
71
|
(record.env === undefined || isNonNullObject(record.env)) &&
|
|
@@ -202,6 +211,9 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
202
211
|
url: typeof serverConfig.url === "string"
|
|
203
212
|
? serverConfig.url
|
|
204
213
|
: undefined,
|
|
214
|
+
blockedTools: Array.isArray(serverConfig.blockedTools)
|
|
215
|
+
? serverConfig.blockedTools
|
|
216
|
+
: undefined,
|
|
205
217
|
metadata: safeMetadataConversion(serverConfig.metadata),
|
|
206
218
|
};
|
|
207
219
|
const result = await this.addServer(serverId, externalConfig);
|
|
@@ -313,6 +325,9 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
313
325
|
url: typeof serverConfig.url === "string"
|
|
314
326
|
? serverConfig.url
|
|
315
327
|
: undefined,
|
|
328
|
+
blockedTools: Array.isArray(serverConfig.blockedTools)
|
|
329
|
+
? serverConfig.blockedTools
|
|
330
|
+
: undefined,
|
|
316
331
|
metadata: safeMetadataConversion(serverConfig.metadata),
|
|
317
332
|
};
|
|
318
333
|
const result = await this.addServer(serverId, externalConfig);
|
|
@@ -403,6 +418,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
403
418
|
args: config.args,
|
|
404
419
|
env: config.env,
|
|
405
420
|
tools: [], // Will be populated after server connection
|
|
421
|
+
blockedTools: config.blockedTools,
|
|
406
422
|
metadata: {
|
|
407
423
|
category: "external",
|
|
408
424
|
// Store additional ExternalMCPServerConfig fields in metadata
|
|
@@ -451,6 +467,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
451
467
|
autoRestart: serverInfo.metadata?.autoRestart,
|
|
452
468
|
cwd: serverInfo.metadata?.cwd,
|
|
453
469
|
url: serverInfo.metadata?.url,
|
|
470
|
+
blockedTools: serverInfo.blockedTools,
|
|
454
471
|
metadata: safeMetadataConversion(serverInfo.metadata),
|
|
455
472
|
};
|
|
456
473
|
const validation = this.validateConfig(tempConfig);
|
|
@@ -1034,7 +1051,15 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1034
1051
|
instance.toolsMap.clear();
|
|
1035
1052
|
instance.toolsArray = undefined;
|
|
1036
1053
|
instance.tools = [];
|
|
1054
|
+
const blockedTools = instance.blockedTools || [];
|
|
1055
|
+
let blockedCount = 0;
|
|
1037
1056
|
for (const tool of discoveryResult.tools) {
|
|
1057
|
+
// Check if tool is blocked
|
|
1058
|
+
if (blockedTools.includes(tool.name)) {
|
|
1059
|
+
mcpLogger.info(`[ExternalServerManager] Blocking tool '${tool.name}' from server '${serverId}' (configured in blockedTools)`);
|
|
1060
|
+
blockedCount++;
|
|
1061
|
+
continue; // Skip blocked tools
|
|
1062
|
+
}
|
|
1038
1063
|
instance.toolsMap.set(tool.name, tool);
|
|
1039
1064
|
instance.tools.push({
|
|
1040
1065
|
name: tool.name,
|
|
@@ -1042,7 +1067,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1042
1067
|
inputSchema: tool.inputSchema,
|
|
1043
1068
|
});
|
|
1044
1069
|
}
|
|
1045
|
-
mcpLogger.info(`[ExternalServerManager] Discovered ${discoveryResult.toolCount} tools for ${serverId}`);
|
|
1070
|
+
mcpLogger.info(`[ExternalServerManager] Discovered ${discoveryResult.toolCount} tools for ${serverId} (${blockedCount} blocked, ${instance.toolsMap.size} available)`);
|
|
1046
1071
|
}
|
|
1047
1072
|
else {
|
|
1048
1073
|
mcpLogger.warn(`[ExternalServerManager] Tool discovery failed for ${serverId}: ${discoveryResult.error}`);
|
|
@@ -1135,6 +1160,11 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1135
1160
|
if (instance.status !== "connected") {
|
|
1136
1161
|
throw new Error(`Server '${serverId}' is not in connected state: ${instance.status}`);
|
|
1137
1162
|
}
|
|
1163
|
+
// Check if tool is blocked
|
|
1164
|
+
const blockedTools = instance.blockedTools || [];
|
|
1165
|
+
if (blockedTools.includes(toolName)) {
|
|
1166
|
+
throw new Error(`Tool '${toolName}' is blocked on server '${serverId}' by configuration`);
|
|
1167
|
+
}
|
|
1138
1168
|
const startTime = Date.now();
|
|
1139
1169
|
try {
|
|
1140
1170
|
// HITL Safety Check: Request confirmation if required
|
|
@@ -37,6 +37,8 @@ export type ExternalMCPServerConfig = {
|
|
|
37
37
|
cwd?: string;
|
|
38
38
|
/** URL for SSE/WebSocket transports */
|
|
39
39
|
url?: string;
|
|
40
|
+
/** List of tool names to block/blacklist from this server */
|
|
41
|
+
blockedTools?: string[];
|
|
40
42
|
/** Additional metadata */
|
|
41
43
|
metadata?: Record<string, JsonValue>;
|
|
42
44
|
};
|
|
@@ -222,6 +222,10 @@ export class PDFProcessor {
|
|
|
222
222
|
const scale = options?.scale || 2.0;
|
|
223
223
|
const format = options?.format || "png";
|
|
224
224
|
const quality = options?.quality || 0.9;
|
|
225
|
+
// Validate format
|
|
226
|
+
if (format !== "png" && format !== "jpeg") {
|
|
227
|
+
throw new Error(`Invalid format: "${format}". Supported formats: "png", "jpeg".`);
|
|
228
|
+
}
|
|
225
229
|
let pdfDocument = null;
|
|
226
230
|
try {
|
|
227
231
|
const loadingTask = pdfjs.getDocument({
|
|
@@ -57,6 +57,15 @@ function isValidExternalMCPServerConfig(config) {
|
|
|
57
57
|
return false;
|
|
58
58
|
}
|
|
59
59
|
const record = config;
|
|
60
|
+
// Validate blockedTools array contains only strings
|
|
61
|
+
if (record.blockedTools !== undefined) {
|
|
62
|
+
if (!Array.isArray(record.blockedTools)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (!record.blockedTools.every((item) => typeof item === "string")) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
60
69
|
return (typeof record.command === "string" &&
|
|
61
70
|
(record.args === undefined || Array.isArray(record.args)) &&
|
|
62
71
|
(record.env === undefined || isNonNullObject(record.env)) &&
|
|
@@ -202,6 +211,9 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
202
211
|
url: typeof serverConfig.url === "string"
|
|
203
212
|
? serverConfig.url
|
|
204
213
|
: undefined,
|
|
214
|
+
blockedTools: Array.isArray(serverConfig.blockedTools)
|
|
215
|
+
? serverConfig.blockedTools
|
|
216
|
+
: undefined,
|
|
205
217
|
metadata: safeMetadataConversion(serverConfig.metadata),
|
|
206
218
|
};
|
|
207
219
|
const result = await this.addServer(serverId, externalConfig);
|
|
@@ -313,6 +325,9 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
313
325
|
url: typeof serverConfig.url === "string"
|
|
314
326
|
? serverConfig.url
|
|
315
327
|
: undefined,
|
|
328
|
+
blockedTools: Array.isArray(serverConfig.blockedTools)
|
|
329
|
+
? serverConfig.blockedTools
|
|
330
|
+
: undefined,
|
|
316
331
|
metadata: safeMetadataConversion(serverConfig.metadata),
|
|
317
332
|
};
|
|
318
333
|
const result = await this.addServer(serverId, externalConfig);
|
|
@@ -403,6 +418,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
403
418
|
args: config.args,
|
|
404
419
|
env: config.env,
|
|
405
420
|
tools: [], // Will be populated after server connection
|
|
421
|
+
blockedTools: config.blockedTools,
|
|
406
422
|
metadata: {
|
|
407
423
|
category: "external",
|
|
408
424
|
// Store additional ExternalMCPServerConfig fields in metadata
|
|
@@ -451,6 +467,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
451
467
|
autoRestart: serverInfo.metadata?.autoRestart,
|
|
452
468
|
cwd: serverInfo.metadata?.cwd,
|
|
453
469
|
url: serverInfo.metadata?.url,
|
|
470
|
+
blockedTools: serverInfo.blockedTools,
|
|
454
471
|
metadata: safeMetadataConversion(serverInfo.metadata),
|
|
455
472
|
};
|
|
456
473
|
const validation = this.validateConfig(tempConfig);
|
|
@@ -1034,7 +1051,15 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1034
1051
|
instance.toolsMap.clear();
|
|
1035
1052
|
instance.toolsArray = undefined;
|
|
1036
1053
|
instance.tools = [];
|
|
1054
|
+
const blockedTools = instance.blockedTools || [];
|
|
1055
|
+
let blockedCount = 0;
|
|
1037
1056
|
for (const tool of discoveryResult.tools) {
|
|
1057
|
+
// Check if tool is blocked
|
|
1058
|
+
if (blockedTools.includes(tool.name)) {
|
|
1059
|
+
mcpLogger.info(`[ExternalServerManager] Blocking tool '${tool.name}' from server '${serverId}' (configured in blockedTools)`);
|
|
1060
|
+
blockedCount++;
|
|
1061
|
+
continue; // Skip blocked tools
|
|
1062
|
+
}
|
|
1038
1063
|
instance.toolsMap.set(tool.name, tool);
|
|
1039
1064
|
instance.tools.push({
|
|
1040
1065
|
name: tool.name,
|
|
@@ -1042,7 +1067,7 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1042
1067
|
inputSchema: tool.inputSchema,
|
|
1043
1068
|
});
|
|
1044
1069
|
}
|
|
1045
|
-
mcpLogger.info(`[ExternalServerManager] Discovered ${discoveryResult.toolCount} tools for ${serverId}`);
|
|
1070
|
+
mcpLogger.info(`[ExternalServerManager] Discovered ${discoveryResult.toolCount} tools for ${serverId} (${blockedCount} blocked, ${instance.toolsMap.size} available)`);
|
|
1046
1071
|
}
|
|
1047
1072
|
else {
|
|
1048
1073
|
mcpLogger.warn(`[ExternalServerManager] Tool discovery failed for ${serverId}: ${discoveryResult.error}`);
|
|
@@ -1135,6 +1160,11 @@ export class ExternalServerManager extends EventEmitter {
|
|
|
1135
1160
|
if (instance.status !== "connected") {
|
|
1136
1161
|
throw new Error(`Server '${serverId}' is not in connected state: ${instance.status}`);
|
|
1137
1162
|
}
|
|
1163
|
+
// Check if tool is blocked
|
|
1164
|
+
const blockedTools = instance.blockedTools || [];
|
|
1165
|
+
if (blockedTools.includes(toolName)) {
|
|
1166
|
+
throw new Error(`Tool '${toolName}' is blocked on server '${serverId}' by configuration`);
|
|
1167
|
+
}
|
|
1138
1168
|
const startTime = Date.now();
|
|
1139
1169
|
try {
|
|
1140
1170
|
// HITL Safety Check: Request confirmation if required
|
|
@@ -37,6 +37,8 @@ export type ExternalMCPServerConfig = {
|
|
|
37
37
|
cwd?: string;
|
|
38
38
|
/** URL for SSE/WebSocket transports */
|
|
39
39
|
url?: string;
|
|
40
|
+
/** List of tool names to block/blacklist from this server */
|
|
41
|
+
blockedTools?: string[];
|
|
40
42
|
/** Additional metadata */
|
|
41
43
|
metadata?: Record<string, JsonValue>;
|
|
42
44
|
};
|
package/dist/types/mcpTypes.d.ts
CHANGED
|
@@ -222,6 +222,10 @@ export class PDFProcessor {
|
|
|
222
222
|
const scale = options?.scale || 2.0;
|
|
223
223
|
const format = options?.format || "png";
|
|
224
224
|
const quality = options?.quality || 0.9;
|
|
225
|
+
// Validate format
|
|
226
|
+
if (format !== "png" && format !== "jpeg") {
|
|
227
|
+
throw new Error(`Invalid format: "${format}". Supported formats: "png", "jpeg".`);
|
|
228
|
+
}
|
|
225
229
|
let pdfDocument = null;
|
|
226
230
|
try {
|
|
227
231
|
const loadingTask = pdfjs.getDocument({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "8.23.
|
|
3
|
+
"version": "8.23.2",
|
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Juspay Technologies",
|