@1mcp/agent 0.22.3 → 0.23.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.
- package/build/commands/mcp/tokens.d.ts +6 -0
- package/build/commands/mcp/tokens.d.ts.map +1 -1
- package/build/commands/mcp/tokens.js +179 -66
- package/build/commands/mcp/tokens.js.map +1 -1
- package/build/commands/preset/interactive.js +1 -2
- package/build/commands/preset/interactive.js.map +1 -1
- package/build/commands/preset/list.js +3 -6
- package/build/commands/preset/list.js.map +1 -1
- package/build/commands/preset/show.js +0 -1
- package/build/commands/preset/show.js.map +1 -1
- package/build/commands/serve/index.d.ts +6 -0
- package/build/commands/serve/index.d.ts.map +1 -1
- package/build/commands/serve/index.js +12 -0
- package/build/commands/serve/index.js.map +1 -1
- package/build/commands/serve/serve.d.ts +1 -0
- package/build/commands/serve/serve.d.ts.map +1 -1
- package/build/commands/serve/serve.js +85 -4
- package/build/commands/serve/serve.js.map +1 -1
- package/build/constants.d.ts +6 -1
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +9 -1
- package/build/constants.js.map +1 -1
- package/build/core/client/clientManager.d.ts +13 -0
- package/build/core/client/clientManager.d.ts.map +1 -1
- package/build/core/client/clientManager.js +48 -0
- package/build/core/client/clientManager.js.map +1 -1
- package/build/core/filtering/filteringService.d.ts +85 -0
- package/build/core/filtering/filteringService.d.ts.map +1 -0
- package/build/core/filtering/filteringService.js +253 -0
- package/build/core/filtering/filteringService.js.map +1 -0
- package/build/core/instructions/instructionAggregator.d.ts +107 -0
- package/build/core/instructions/instructionAggregator.d.ts.map +1 -0
- package/build/core/instructions/instructionAggregator.js +277 -0
- package/build/core/instructions/instructionAggregator.js.map +1 -0
- package/build/core/instructions/templateTypes.d.ts +79 -0
- package/build/core/instructions/templateTypes.d.ts.map +1 -0
- package/build/core/instructions/templateTypes.js +91 -0
- package/build/core/instructions/templateTypes.js.map +1 -0
- package/build/core/instructions/templateValidator.d.ts +82 -0
- package/build/core/instructions/templateValidator.d.ts.map +1 -0
- package/build/core/instructions/templateValidator.js +244 -0
- package/build/core/instructions/templateValidator.js.map +1 -0
- package/build/core/server/serverManager.d.ts +11 -0
- package/build/core/server/serverManager.d.ts.map +1 -1
- package/build/core/server/serverManager.js +38 -1
- package/build/core/server/serverManager.js.map +1 -1
- package/build/core/types/client.d.ts +2 -0
- package/build/core/types/client.d.ts.map +1 -1
- package/build/core/types/server.d.ts +2 -1
- package/build/core/types/server.d.ts.map +1 -1
- package/build/core/types/server.js.map +1 -1
- package/build/handlers/requestHandlers.d.ts.map +1 -1
- package/build/handlers/requestHandlers.js +14 -42
- package/build/handlers/requestHandlers.js.map +1 -1
- package/build/server.d.ts +3 -0
- package/build/server.d.ts.map +1 -1
- package/build/server.js +13 -0
- package/build/server.js.map +1 -1
- package/build/transport/http/routes/sseRoutes.d.ts +1 -1
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/sseRoutes.js +2 -1
- package/build/transport/http/routes/sseRoutes.js.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.js +2 -1
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
- package/build/transport/http/server.d.ts +3 -1
- package/build/transport/http/server.d.ts.map +1 -1
- package/build/transport/http/server.js +6 -3
- package/build/transport/http/server.js.map +1 -1
- package/build/utils/presetManager.d.ts +0 -4
- package/build/utils/presetManager.d.ts.map +1 -1
- package/build/utils/presetManager.js +0 -16
- package/build/utils/presetManager.js.map +1 -1
- package/build/utils/presetTypes.d.ts +0 -3
- package/build/utils/presetTypes.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Individual server data for template iteration
|
|
3
|
+
*/
|
|
4
|
+
export interface ServerData {
|
|
5
|
+
/** Server name (e.g., "api-server") */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Server instructions content */
|
|
8
|
+
instructions: string;
|
|
9
|
+
/** Whether this server has instructions */
|
|
10
|
+
hasInstructions: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Template variables available for custom instruction templates
|
|
14
|
+
* These variables are provided by 1MCP and can be used in Handlebars templates
|
|
15
|
+
*/
|
|
16
|
+
export interface TemplateVariables {
|
|
17
|
+
/** Number of connected servers (e.g., 3) */
|
|
18
|
+
serverCount: number;
|
|
19
|
+
/** Boolean indicating if any servers are connected */
|
|
20
|
+
hasServers: boolean;
|
|
21
|
+
/** Newline-separated list of server names */
|
|
22
|
+
serverList: string;
|
|
23
|
+
/** Array of server names for iteration with {{#each}} */
|
|
24
|
+
serverNames: string[];
|
|
25
|
+
/** Array of server objects for detailed iteration with {{#each}} */
|
|
26
|
+
servers: ServerData[];
|
|
27
|
+
/** "server" or "servers" based on count */
|
|
28
|
+
pluralServers: string;
|
|
29
|
+
/** "is" or "are" based on count */
|
|
30
|
+
isAre: string;
|
|
31
|
+
/** All server instructions wrapped in XML-like tags */
|
|
32
|
+
instructions: string;
|
|
33
|
+
/** Filter description (e.g., " (filtered by tags: backend)") or empty string */
|
|
34
|
+
filterContext: string;
|
|
35
|
+
/** Tool naming pattern (default: "{server}_1mcp_{tool}") */
|
|
36
|
+
toolPattern: string;
|
|
37
|
+
/** Title for the template (default: "1MCP - Model Context Protocol Proxy") */
|
|
38
|
+
title: string;
|
|
39
|
+
/** Array of tool examples for documentation */
|
|
40
|
+
examples: TemplateExample[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Tool example for template documentation
|
|
44
|
+
*/
|
|
45
|
+
export interface TemplateExample {
|
|
46
|
+
/** Tool name with pattern applied (e.g., "filesystem_1mcp_read_file") */
|
|
47
|
+
name: string;
|
|
48
|
+
/** Description of what the tool does */
|
|
49
|
+
description: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Template configuration options
|
|
53
|
+
*/
|
|
54
|
+
export interface TemplateConfig {
|
|
55
|
+
/** Custom Handlebars template string */
|
|
56
|
+
customTemplate?: string;
|
|
57
|
+
/** Override default title */
|
|
58
|
+
title?: string;
|
|
59
|
+
/** Override default tool pattern */
|
|
60
|
+
toolPattern?: string;
|
|
61
|
+
/** Custom tool examples */
|
|
62
|
+
examples?: TemplateExample[];
|
|
63
|
+
/** Maximum template size in bytes (default: 1MB) */
|
|
64
|
+
templateSizeLimit?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Default template examples
|
|
68
|
+
*/
|
|
69
|
+
export declare const DEFAULT_TEMPLATE_EXAMPLES: TemplateExample[];
|
|
70
|
+
/**
|
|
71
|
+
* Default template configuration values
|
|
72
|
+
*/
|
|
73
|
+
export declare const DEFAULT_TEMPLATE_CONFIG: Required<Omit<TemplateConfig, 'customTemplate'>>;
|
|
74
|
+
/**
|
|
75
|
+
* Default instruction template using Handlebars syntax
|
|
76
|
+
* This template is used when no custom template is provided
|
|
77
|
+
*/
|
|
78
|
+
export declare const DEFAULT_INSTRUCTION_TEMPLATE = "# {{title}}\n\n{{#if hasServers}}\nYou are interacting with 1MCP, a proxy server that aggregates capabilities from multiple MCP (Model Context Protocol) servers. 1MCP acts as a unified gateway, allowing you to access tools and resources from various specialized MCP servers through a single connection.\n\n## How 1MCP Works\n\n- **Unified Access**: Connect to multiple MCP servers through one proxy\n- **Tool Aggregation**: All tools are available with the naming pattern `{{toolPattern}}`\n- **Resource Sharing**: Access files, data, and capabilities across different servers\n- **Intelligent Routing**: Your requests are automatically routed to the appropriate servers\n\n## Currently Connected Servers\n\n{{serverCount}} MCP {{pluralServers}} {{isAre}} currently available{{filterContext}}:\n\n{{serverList}}\n\n## Available Capabilities\n\nAll tools from connected servers are accessible using the format: `{{toolPattern}}`\n\nExamples:\n{{#each examples}}\n- `{{name}}` - {{description}}\n{{/each}}\n\n## Server-Specific Instructions\n\nThe following sections contain instructions from each connected MCP server. Each server's instructions are wrapped in XML-like tags (e.g., `<server-name>instructions</server-name>`) to clearly identify their source and scope.\n\n{{#each servers}}\n{{#if hasInstructions}}\n<{{name}}>\n{{instructions}}\n</{{name}}>\n\n{{/if}}\n{{/each}}\n\n## Tips for Using 1MCP\n\n- Tools are namespaced by server to avoid conflicts\n\n{{else}}\nYou are interacting with 1MCP, a proxy server that aggregates capabilities from multiple MCP (Model Context Protocol) servers.\n\n## Current Status\n\nNo MCP servers are currently connected. 1MCP is ready to connect to servers and provide unified access to their capabilities once they become available.\n\n## What 1MCP Provides\n\n- **Unified Access**: Connect to multiple MCP servers through one proxy\n- **Tool Aggregation**: Access tools using the pattern `{{toolPattern}}`\n- **Resource Sharing**: Share files, data, and capabilities across servers\n- **Intelligent Routing**: Automatic request routing to appropriate servers\n\n1MCP will automatically detect and connect to available MCP servers. Once connected, their tools and capabilities will become available through the unified interface.\n{{/if}}";
|
|
79
|
+
//# sourceMappingURL=templateTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateTypes.d.ts","sourceRoot":"","sources":["../../../src/core/instructions/templateTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IAErB,2CAA2C;IAC3C,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAEhC,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IAEpB,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IAEnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB,oEAAoE;IACpE,OAAO,EAAE,UAAU,EAAE,CAAC;IAEtB,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;IAEtB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IAGd,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IAErB,gFAAgF;IAChF,aAAa,EAAE,MAAM,CAAC;IAGtB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IAEpB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IAEd,+CAA+C;IAC/C,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IAEb,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAE7B,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,eAAe,EAatD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAKpF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,+uEA2DjC,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default template examples
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_TEMPLATE_EXAMPLES = [
|
|
5
|
+
{
|
|
6
|
+
name: 'filesystem_1mcp_read_file',
|
|
7
|
+
description: 'Read files through filesystem server',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'web_1mcp_search',
|
|
11
|
+
description: 'Search the web through web server',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'database_1mcp_query',
|
|
15
|
+
description: 'Query databases through database server',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Default template configuration values
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_TEMPLATE_CONFIG = {
|
|
22
|
+
title: '1MCP - Model Context Protocol Proxy',
|
|
23
|
+
toolPattern: '{server}_1mcp_{tool}',
|
|
24
|
+
examples: DEFAULT_TEMPLATE_EXAMPLES,
|
|
25
|
+
templateSizeLimit: 1024 * 1024, // 1MB default
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Default instruction template using Handlebars syntax
|
|
29
|
+
* This template is used when no custom template is provided
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_INSTRUCTION_TEMPLATE = `# {{title}}
|
|
32
|
+
|
|
33
|
+
{{#if hasServers}}
|
|
34
|
+
You are interacting with 1MCP, a proxy server that aggregates capabilities from multiple MCP (Model Context Protocol) servers. 1MCP acts as a unified gateway, allowing you to access tools and resources from various specialized MCP servers through a single connection.
|
|
35
|
+
|
|
36
|
+
## How 1MCP Works
|
|
37
|
+
|
|
38
|
+
- **Unified Access**: Connect to multiple MCP servers through one proxy
|
|
39
|
+
- **Tool Aggregation**: All tools are available with the naming pattern \`{{toolPattern}}\`
|
|
40
|
+
- **Resource Sharing**: Access files, data, and capabilities across different servers
|
|
41
|
+
- **Intelligent Routing**: Your requests are automatically routed to the appropriate servers
|
|
42
|
+
|
|
43
|
+
## Currently Connected Servers
|
|
44
|
+
|
|
45
|
+
{{serverCount}} MCP {{pluralServers}} {{isAre}} currently available{{filterContext}}:
|
|
46
|
+
|
|
47
|
+
{{serverList}}
|
|
48
|
+
|
|
49
|
+
## Available Capabilities
|
|
50
|
+
|
|
51
|
+
All tools from connected servers are accessible using the format: \`{{toolPattern}}\`
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
{{#each examples}}
|
|
55
|
+
- \`{{name}}\` - {{description}}
|
|
56
|
+
{{/each}}
|
|
57
|
+
|
|
58
|
+
## Server-Specific Instructions
|
|
59
|
+
|
|
60
|
+
The following sections contain instructions from each connected MCP server. Each server's instructions are wrapped in XML-like tags (e.g., \`<server-name>instructions</server-name>\`) to clearly identify their source and scope.
|
|
61
|
+
|
|
62
|
+
{{#each servers}}
|
|
63
|
+
{{#if hasInstructions}}
|
|
64
|
+
<{{name}}>
|
|
65
|
+
{{instructions}}
|
|
66
|
+
</{{name}}>
|
|
67
|
+
|
|
68
|
+
{{/if}}
|
|
69
|
+
{{/each}}
|
|
70
|
+
|
|
71
|
+
## Tips for Using 1MCP
|
|
72
|
+
|
|
73
|
+
- Tools are namespaced by server to avoid conflicts
|
|
74
|
+
|
|
75
|
+
{{else}}
|
|
76
|
+
You are interacting with 1MCP, a proxy server that aggregates capabilities from multiple MCP (Model Context Protocol) servers.
|
|
77
|
+
|
|
78
|
+
## Current Status
|
|
79
|
+
|
|
80
|
+
No MCP servers are currently connected. 1MCP is ready to connect to servers and provide unified access to their capabilities once they become available.
|
|
81
|
+
|
|
82
|
+
## What 1MCP Provides
|
|
83
|
+
|
|
84
|
+
- **Unified Access**: Connect to multiple MCP servers through one proxy
|
|
85
|
+
- **Tool Aggregation**: Access tools using the pattern \`{{toolPattern}}\`
|
|
86
|
+
- **Resource Sharing**: Share files, data, and capabilities across servers
|
|
87
|
+
- **Intelligent Routing**: Automatic request routing to appropriate servers
|
|
88
|
+
|
|
89
|
+
1MCP will automatically detect and connect to available MCP servers. Once connected, their tools and capabilities will become available through the unified interface.
|
|
90
|
+
{{/if}}`;
|
|
91
|
+
//# sourceMappingURL=templateTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateTypes.js","sourceRoot":"","sources":["../../../src/core/instructions/templateTypes.ts"],"names":[],"mappings":"AA0FA;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D;QACE,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,sCAAsC;KACpD;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,mCAAmC;KACjD;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAqD;IACvF,KAAK,EAAE,qCAAqC;IAC5C,WAAW,EAAE,sBAAsB;IACnC,QAAQ,EAAE,yBAAyB;IACnC,iBAAiB,EAAE,IAAI,GAAG,IAAI,EAAE,cAAc;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA2DpC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types of template errors for better categorization
|
|
3
|
+
*/
|
|
4
|
+
export declare enum TemplateErrorType {
|
|
5
|
+
/** Handlebars syntax errors (unmatched braces, invalid expressions) */
|
|
6
|
+
SYNTAX = "SYNTAX",
|
|
7
|
+
/** Template compilation errors (missing helpers, invalid helper usage) */
|
|
8
|
+
COMPILATION = "COMPILATION",
|
|
9
|
+
/** Template size exceeds allowed limit */
|
|
10
|
+
SIZE_LIMIT = "SIZE_LIMIT",
|
|
11
|
+
/** Template contains potentially unsafe content */
|
|
12
|
+
UNSAFE_CONTENT = "UNSAFE_CONTENT",
|
|
13
|
+
/** Runtime errors during template rendering */
|
|
14
|
+
RUNTIME = "RUNTIME"
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Template validation result with error details if invalid
|
|
18
|
+
*/
|
|
19
|
+
export interface TemplateValidationResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
errorType?: TemplateErrorType;
|
|
23
|
+
suggestions?: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for template validation
|
|
27
|
+
*/
|
|
28
|
+
export interface TemplateValidationConfig {
|
|
29
|
+
maxSizeBytes?: number;
|
|
30
|
+
allowUnsafeContent?: boolean;
|
|
31
|
+
customDangerousPatterns?: RegExp[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Default validation configuration
|
|
35
|
+
*/
|
|
36
|
+
export declare const DEFAULT_TEMPLATE_VALIDATION_CONFIG: Required<TemplateValidationConfig>;
|
|
37
|
+
/**
|
|
38
|
+
* Built-in dangerous patterns for template content
|
|
39
|
+
*/
|
|
40
|
+
export declare const DANGEROUS_TEMPLATE_PATTERNS: RegExp[];
|
|
41
|
+
/**
|
|
42
|
+
* Categorize template errors based on error message patterns
|
|
43
|
+
* @param errorMessage Error message from Handlebars compilation
|
|
44
|
+
* @returns Template error type
|
|
45
|
+
*/
|
|
46
|
+
export declare function categorizeTemplateError(errorMessage: string): TemplateErrorType;
|
|
47
|
+
/**
|
|
48
|
+
* Get specific suggestions based on error type
|
|
49
|
+
* @param errorType Type of template error
|
|
50
|
+
* @param errorMessage Original error message
|
|
51
|
+
* @returns Array of suggestions
|
|
52
|
+
*/
|
|
53
|
+
export declare function getErrorSuggestions(errorType: TemplateErrorType, errorMessage: string): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Validate Handlebars template content for safety and syntax
|
|
56
|
+
* @param templateContent Template content to validate
|
|
57
|
+
* @param templatePath Path for error reporting (optional)
|
|
58
|
+
* @param config Validation configuration (optional)
|
|
59
|
+
* @returns Validation result with error details if invalid
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateTemplateContent(templateContent: string, templatePath?: string, config?: TemplateValidationConfig): TemplateValidationResult;
|
|
62
|
+
/**
|
|
63
|
+
* Validate template file size before reading
|
|
64
|
+
* @param filePath Path to template file
|
|
65
|
+
* @param maxSizeBytes Maximum allowed file size in bytes
|
|
66
|
+
* @returns True if file size is acceptable
|
|
67
|
+
*/
|
|
68
|
+
export declare function isTemplateSizeAcceptable(filePath: string, maxSizeBytes?: number): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Quick validation for template content safety (without compilation)
|
|
71
|
+
* @param templateContent Template content to check
|
|
72
|
+
* @param config Validation configuration
|
|
73
|
+
* @returns True if content appears safe
|
|
74
|
+
*/
|
|
75
|
+
export declare function isTemplateContentSafe(templateContent: string, config?: TemplateValidationConfig): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Get human-readable validation error message with suggestions
|
|
78
|
+
* @param result Validation result from validateTemplateContent
|
|
79
|
+
* @returns Formatted error message with suggestions
|
|
80
|
+
*/
|
|
81
|
+
export declare function formatValidationError(result: TemplateValidationResult): string;
|
|
82
|
+
//# sourceMappingURL=templateValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateValidator.d.ts","sourceRoot":"","sources":["../../../src/core/instructions/templateValidator.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,uEAAuE;IACvE,MAAM,WAAW;IACjB,0EAA0E;IAC1E,WAAW,gBAAgB;IAC3B,0CAA0C;IAC1C,UAAU,eAAe;IACzB,mDAAmD;IACnD,cAAc,mBAAmB;IACjC,+CAA+C;IAC/C,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CAAC,wBAAwB,CAIjF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,EAI/C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,CA2B/E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAkDhG;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,GAAE,wBAA6B,GACpC,wBAAwB,CA6E1B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,GAAE,MAAwD,GACrE,OAAO,CAQT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,GAAE,wBAA6B,GAAG,OAAO,CAS7G;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CAe9E"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import Handlebars from 'handlebars';
|
|
2
|
+
/**
|
|
3
|
+
* Types of template errors for better categorization
|
|
4
|
+
*/
|
|
5
|
+
export var TemplateErrorType;
|
|
6
|
+
(function (TemplateErrorType) {
|
|
7
|
+
/** Handlebars syntax errors (unmatched braces, invalid expressions) */
|
|
8
|
+
TemplateErrorType["SYNTAX"] = "SYNTAX";
|
|
9
|
+
/** Template compilation errors (missing helpers, invalid helper usage) */
|
|
10
|
+
TemplateErrorType["COMPILATION"] = "COMPILATION";
|
|
11
|
+
/** Template size exceeds allowed limit */
|
|
12
|
+
TemplateErrorType["SIZE_LIMIT"] = "SIZE_LIMIT";
|
|
13
|
+
/** Template contains potentially unsafe content */
|
|
14
|
+
TemplateErrorType["UNSAFE_CONTENT"] = "UNSAFE_CONTENT";
|
|
15
|
+
/** Runtime errors during template rendering */
|
|
16
|
+
TemplateErrorType["RUNTIME"] = "RUNTIME";
|
|
17
|
+
})(TemplateErrorType || (TemplateErrorType = {}));
|
|
18
|
+
/**
|
|
19
|
+
* Default validation configuration
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_TEMPLATE_VALIDATION_CONFIG = {
|
|
22
|
+
maxSizeBytes: 1024 * 1024, // 1MB
|
|
23
|
+
allowUnsafeContent: false,
|
|
24
|
+
customDangerousPatterns: [],
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Built-in dangerous patterns for template content
|
|
28
|
+
*/
|
|
29
|
+
export const DANGEROUS_TEMPLATE_PATTERNS = [
|
|
30
|
+
/<script[^>]*>/i,
|
|
31
|
+
/javascript:/i,
|
|
32
|
+
/on\w+\s*=/i, // event handlers like onclick=
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Categorize template errors based on error message patterns
|
|
36
|
+
* @param errorMessage Error message from Handlebars compilation
|
|
37
|
+
* @returns Template error type
|
|
38
|
+
*/
|
|
39
|
+
export function categorizeTemplateError(errorMessage) {
|
|
40
|
+
const message = errorMessage.toLowerCase();
|
|
41
|
+
// Check for syntax errors
|
|
42
|
+
if (message.includes('parse error') ||
|
|
43
|
+
message.includes('expecting') ||
|
|
44
|
+
message.includes('unexpected token') ||
|
|
45
|
+
message.includes('unterminated') ||
|
|
46
|
+
message.includes('unmatched') ||
|
|
47
|
+
message.includes("doesn't match")) {
|
|
48
|
+
return TemplateErrorType.SYNTAX;
|
|
49
|
+
}
|
|
50
|
+
// Check for compilation errors
|
|
51
|
+
if (message.includes('missing helper') ||
|
|
52
|
+
message.includes('must pass iterator') ||
|
|
53
|
+
message.includes('helper not found') ||
|
|
54
|
+
message.includes('invalid helper')) {
|
|
55
|
+
return TemplateErrorType.COMPILATION;
|
|
56
|
+
}
|
|
57
|
+
// Default to compilation error for other Handlebars errors
|
|
58
|
+
return TemplateErrorType.COMPILATION;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get specific suggestions based on error type
|
|
62
|
+
* @param errorType Type of template error
|
|
63
|
+
* @param errorMessage Original error message
|
|
64
|
+
* @returns Array of suggestions
|
|
65
|
+
*/
|
|
66
|
+
export function getErrorSuggestions(errorType, errorMessage) {
|
|
67
|
+
switch (errorType) {
|
|
68
|
+
case TemplateErrorType.SYNTAX:
|
|
69
|
+
return [
|
|
70
|
+
'Check for unmatched braces {{ }}',
|
|
71
|
+
'Ensure all Handlebars expressions are properly closed',
|
|
72
|
+
'Verify nested expressions have correct syntax',
|
|
73
|
+
'Look for unterminated block helpers like {{#if}} without {{/if}}',
|
|
74
|
+
];
|
|
75
|
+
case TemplateErrorType.COMPILATION:
|
|
76
|
+
if (errorMessage.includes('Must pass iterator')) {
|
|
77
|
+
return [
|
|
78
|
+
'Use {{#each serverNames}} instead of {{#each}}',
|
|
79
|
+
'Ensure iterator variable is provided for #each helpers',
|
|
80
|
+
'Check available template variables in documentation',
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
return [
|
|
84
|
+
'Use only built-in Handlebars helpers',
|
|
85
|
+
'Check available template variables in documentation',
|
|
86
|
+
'Verify helper names are spelled correctly',
|
|
87
|
+
'Ensure block helpers like {{#if}} have matching {{/if}}',
|
|
88
|
+
];
|
|
89
|
+
case TemplateErrorType.SIZE_LIMIT:
|
|
90
|
+
return [
|
|
91
|
+
'Consider splitting the template into smaller files',
|
|
92
|
+
'Remove unnecessary content or comments',
|
|
93
|
+
'Use template partials for repeated sections',
|
|
94
|
+
'Increase template size limit if necessary',
|
|
95
|
+
];
|
|
96
|
+
case TemplateErrorType.UNSAFE_CONTENT:
|
|
97
|
+
return [
|
|
98
|
+
'Remove script tags and event handlers',
|
|
99
|
+
'Use safe template variables only',
|
|
100
|
+
'Consider using triple braces {{{content}}} only for trusted content',
|
|
101
|
+
'Review template security best practices',
|
|
102
|
+
];
|
|
103
|
+
case TemplateErrorType.RUNTIME:
|
|
104
|
+
return [
|
|
105
|
+
'Check template variables are correctly defined',
|
|
106
|
+
'Verify data passed to template matches expected structure',
|
|
107
|
+
'Test template with sample data',
|
|
108
|
+
];
|
|
109
|
+
default:
|
|
110
|
+
return [
|
|
111
|
+
'Check Handlebars documentation for proper syntax',
|
|
112
|
+
'Test template with a simple Handlebars validator',
|
|
113
|
+
'Start with a minimal template and add complexity gradually',
|
|
114
|
+
];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate Handlebars template content for safety and syntax
|
|
119
|
+
* @param templateContent Template content to validate
|
|
120
|
+
* @param templatePath Path for error reporting (optional)
|
|
121
|
+
* @param config Validation configuration (optional)
|
|
122
|
+
* @returns Validation result with error details if invalid
|
|
123
|
+
*/
|
|
124
|
+
export function validateTemplateContent(templateContent, templatePath, config = {}) {
|
|
125
|
+
const validationConfig = { ...DEFAULT_TEMPLATE_VALIDATION_CONFIG, ...config };
|
|
126
|
+
const pathInfo = templatePath ? ` at ${templatePath}` : '';
|
|
127
|
+
// Check template size
|
|
128
|
+
if (templateContent.length > validationConfig.maxSizeBytes) {
|
|
129
|
+
return {
|
|
130
|
+
valid: false,
|
|
131
|
+
error: `Template file too large${pathInfo}: ${templateContent.length} bytes (max ${Math.round(validationConfig.maxSizeBytes / 1024 / 1024)}MB)`,
|
|
132
|
+
errorType: TemplateErrorType.SIZE_LIMIT,
|
|
133
|
+
suggestions: getErrorSuggestions(TemplateErrorType.SIZE_LIMIT, ''),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// Check for potentially dangerous content (unless explicitly allowed)
|
|
137
|
+
if (!validationConfig.allowUnsafeContent) {
|
|
138
|
+
const allPatterns = [...DANGEROUS_TEMPLATE_PATTERNS, ...validationConfig.customDangerousPatterns];
|
|
139
|
+
for (const pattern of allPatterns) {
|
|
140
|
+
if (pattern.test(templateContent)) {
|
|
141
|
+
return {
|
|
142
|
+
valid: false,
|
|
143
|
+
error: `Template contains potentially unsafe content${pathInfo}: ${pattern.source}`,
|
|
144
|
+
errorType: TemplateErrorType.UNSAFE_CONTENT,
|
|
145
|
+
suggestions: getErrorSuggestions(TemplateErrorType.UNSAFE_CONTENT, ''),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Validate Handlebars syntax by attempting compilation and rendering
|
|
151
|
+
try {
|
|
152
|
+
const compiledTemplate = Handlebars.compile(templateContent, { noEscape: true });
|
|
153
|
+
// Try rendering with sample data to catch runtime errors
|
|
154
|
+
try {
|
|
155
|
+
compiledTemplate({
|
|
156
|
+
serverCount: 0,
|
|
157
|
+
hasServers: false,
|
|
158
|
+
serverList: '',
|
|
159
|
+
serverNames: [],
|
|
160
|
+
servers: [],
|
|
161
|
+
pluralServers: 'servers',
|
|
162
|
+
isAre: 'are',
|
|
163
|
+
instructions: '',
|
|
164
|
+
filterContext: '',
|
|
165
|
+
toolPattern: '{server}_1mcp_{tool}',
|
|
166
|
+
title: 'Test Title',
|
|
167
|
+
examples: [],
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (renderError) {
|
|
171
|
+
// If rendering fails, it's a compilation/runtime error
|
|
172
|
+
const errorMessage = renderError instanceof Error ? renderError.message : String(renderError);
|
|
173
|
+
const errorType = categorizeTemplateError(errorMessage);
|
|
174
|
+
const suggestions = getErrorSuggestions(errorType, errorMessage);
|
|
175
|
+
return {
|
|
176
|
+
valid: false,
|
|
177
|
+
error: `Template syntax error${pathInfo}: ${errorMessage}`,
|
|
178
|
+
errorType,
|
|
179
|
+
suggestions,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return { valid: true };
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
186
|
+
const errorType = categorizeTemplateError(errorMessage);
|
|
187
|
+
const suggestions = getErrorSuggestions(errorType, errorMessage);
|
|
188
|
+
return {
|
|
189
|
+
valid: false,
|
|
190
|
+
error: `Template syntax error${pathInfo}: ${errorMessage}`,
|
|
191
|
+
errorType,
|
|
192
|
+
suggestions,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Validate template file size before reading
|
|
198
|
+
* @param filePath Path to template file
|
|
199
|
+
* @param maxSizeBytes Maximum allowed file size in bytes
|
|
200
|
+
* @returns True if file size is acceptable
|
|
201
|
+
*/
|
|
202
|
+
export function isTemplateSizeAcceptable(filePath, maxSizeBytes = DEFAULT_TEMPLATE_VALIDATION_CONFIG.maxSizeBytes) {
|
|
203
|
+
try {
|
|
204
|
+
const fs = require('fs');
|
|
205
|
+
const stats = fs.statSync(filePath);
|
|
206
|
+
return stats.size <= maxSizeBytes;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return false; // File doesn't exist or can't be accessed
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Quick validation for template content safety (without compilation)
|
|
214
|
+
* @param templateContent Template content to check
|
|
215
|
+
* @param config Validation configuration
|
|
216
|
+
* @returns True if content appears safe
|
|
217
|
+
*/
|
|
218
|
+
export function isTemplateContentSafe(templateContent, config = {}) {
|
|
219
|
+
const validationConfig = { ...DEFAULT_TEMPLATE_VALIDATION_CONFIG, ...config };
|
|
220
|
+
if (!validationConfig.allowUnsafeContent) {
|
|
221
|
+
const allPatterns = [...DANGEROUS_TEMPLATE_PATTERNS, ...validationConfig.customDangerousPatterns];
|
|
222
|
+
return !allPatterns.some((pattern) => pattern.test(templateContent));
|
|
223
|
+
}
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get human-readable validation error message with suggestions
|
|
228
|
+
* @param result Validation result from validateTemplateContent
|
|
229
|
+
* @returns Formatted error message with suggestions
|
|
230
|
+
*/
|
|
231
|
+
export function formatValidationError(result) {
|
|
232
|
+
if (result.valid) {
|
|
233
|
+
return '';
|
|
234
|
+
}
|
|
235
|
+
let message = result.error || 'Template validation failed';
|
|
236
|
+
if (result.suggestions && result.suggestions.length > 0) {
|
|
237
|
+
message += '\n\nSuggestions:';
|
|
238
|
+
result.suggestions.forEach((suggestion, index) => {
|
|
239
|
+
message += `\n ${index + 1}. ${suggestion}`;
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return message;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=templateValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateValidator.js","sourceRoot":"","sources":["../../../src/core/instructions/templateValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
2
|
import { OutboundConnections, InboundConnection, InboundConnectionConfig, OperationOptions } from '../types/index.js';
|
|
3
3
|
import type { OutboundConnection } from '../types/client.js';
|
|
4
|
+
import { InstructionAggregator } from '../instructions/instructionAggregator.js';
|
|
4
5
|
export declare class ServerManager {
|
|
5
6
|
private static instance;
|
|
6
7
|
private inboundConns;
|
|
@@ -10,6 +11,7 @@ export declare class ServerManager {
|
|
|
10
11
|
private transports;
|
|
11
12
|
private connectionSemaphore;
|
|
12
13
|
private disconnectingIds;
|
|
14
|
+
private instructionAggregator?;
|
|
13
15
|
private constructor();
|
|
14
16
|
static getOrCreateInstance(config: {
|
|
15
17
|
name: string;
|
|
@@ -19,6 +21,15 @@ export declare class ServerManager {
|
|
|
19
21
|
}, outboundConns: OutboundConnections, transports: Record<string, Transport>): ServerManager;
|
|
20
22
|
static get current(): ServerManager;
|
|
21
23
|
static resetInstance(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Set the instruction aggregator instance
|
|
26
|
+
* @param aggregator The instruction aggregator to use
|
|
27
|
+
*/
|
|
28
|
+
setInstructionAggregator(aggregator: InstructionAggregator): void;
|
|
29
|
+
/**
|
|
30
|
+
* Update all server instances with new aggregated instructions
|
|
31
|
+
*/
|
|
32
|
+
private updateServerInstructions;
|
|
22
33
|
connectTransport(transport: Transport, sessionId: string, opts: InboundConnectionConfig): Promise<void>;
|
|
23
34
|
private performConnection;
|
|
24
35
|
private doConnect;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverManager.d.ts","sourceRoot":"","sources":["../../../src/core/server/serverManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAM1E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"serverManager.d.ts","sourceRoot":"","sources":["../../../src/core/server/serverManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAM1E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,YAAY,CAA6C;IACjE,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,kBAAkB,CAA4C;IAEtE,OAAO,CAAC,aAAa,CAA8D;IACnF,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,mBAAmB,CAAyC;IACpE,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,qBAAqB,CAAC,CAAwB;IAEtD,OAAO;WAYO,mBAAmB,CAC/B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EACzC,YAAY,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EACvD,aAAa,EAAE,mBAAmB,EAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GACpC,aAAa;IAOhB,WAAkB,OAAO,IAAI,aAAa,CAKzC;WAGa,aAAa,IAAI,IAAI;IAanC;;;OAGG;IACI,wBAAwB,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI;IAWxE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAenB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BtG,iBAAiB;YA2BjB,SAAS;IA4EhB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,IAAI;IAsCzE,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItD,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;IAUvC,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;IAIhD,UAAU,IAAI,mBAAmB;IAIxC;;;OAGG;IACI,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI7D,wBAAwB,IAAI,MAAM;IAIlC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAI3D,qBAAqB,IAAI,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAIvD,0BAA0B,CAAC,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI;IAKlH;;;;;OAKG;IACU,sBAAsB,CAAC,CAAC,EACnC,WAAW,EAAE,iBAAiB,EAC9B,SAAS,EAAE,CAAC,WAAW,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,EACzD,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,CAAC,CAAC;CAQd"}
|
|
@@ -15,6 +15,7 @@ export class ServerManager {
|
|
|
15
15
|
transports = {};
|
|
16
16
|
connectionSemaphore = new Map();
|
|
17
17
|
disconnectingIds = new Set();
|
|
18
|
+
instructionAggregator;
|
|
18
19
|
constructor(config, capabilities, outboundConns, transports) {
|
|
19
20
|
this.serverConfig = config;
|
|
20
21
|
this.serverCapabilities = capabilities;
|
|
@@ -46,6 +47,35 @@ export class ServerManager {
|
|
|
46
47
|
}
|
|
47
48
|
ServerManager.instance = undefined;
|
|
48
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Set the instruction aggregator instance
|
|
52
|
+
* @param aggregator The instruction aggregator to use
|
|
53
|
+
*/
|
|
54
|
+
setInstructionAggregator(aggregator) {
|
|
55
|
+
this.instructionAggregator = aggregator;
|
|
56
|
+
// Listen for instruction changes and update existing server instances
|
|
57
|
+
aggregator.on('instructions-changed', () => {
|
|
58
|
+
this.updateServerInstructions();
|
|
59
|
+
});
|
|
60
|
+
logger.debug('Instruction aggregator set for ServerManager');
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update all server instances with new aggregated instructions
|
|
64
|
+
*/
|
|
65
|
+
updateServerInstructions() {
|
|
66
|
+
logger.info(`Server instructions have changed. Active sessions: ${this.inboundConns.size}`);
|
|
67
|
+
for (const [sessionId, _inboundConn] of this.inboundConns) {
|
|
68
|
+
try {
|
|
69
|
+
// Note: The MCP SDK doesn't provide a direct way to update instructions
|
|
70
|
+
// on an existing server instance. Instructions are set during server construction.
|
|
71
|
+
// For now, we'll log this for future server instances.
|
|
72
|
+
logger.debug(`Instructions changed notification for session ${sessionId}`);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
logger.warn(`Failed to process instruction change for session ${sessionId}: ${error}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
49
79
|
async connectTransport(transport, sessionId, opts) {
|
|
50
80
|
// Check if a connection is already in progress for this session
|
|
51
81
|
const existingConnection = this.connectionSemaphore.get(sessionId);
|
|
@@ -91,8 +121,15 @@ export class ServerManager {
|
|
|
91
121
|
}
|
|
92
122
|
}
|
|
93
123
|
async doConnect(transport, sessionId, opts) {
|
|
124
|
+
// Get filtered instructions based on client's filter criteria using InstructionAggregator
|
|
125
|
+
const filteredInstructions = this.instructionAggregator?.getFilteredInstructions(opts, this.outboundConns) || '';
|
|
126
|
+
// Create server capabilities with filtered instructions
|
|
127
|
+
const serverOptionsWithInstructions = {
|
|
128
|
+
...this.serverCapabilities,
|
|
129
|
+
instructions: filteredInstructions || undefined,
|
|
130
|
+
};
|
|
94
131
|
// Create a new server instance for this transport
|
|
95
|
-
const server = new Server(this.serverConfig,
|
|
132
|
+
const server = new Server(this.serverConfig, serverOptionsWithInstructions);
|
|
96
133
|
// Create server info object first
|
|
97
134
|
const serverInfo = {
|
|
98
135
|
server,
|